舉一個簡單java調優例子,一個大對象導致full GC的例子
下面是一個產生大對象,MinorGC的時候總有很多的大對象沒有被回收,需要將這些對象放入到年老帶中,導致年老帶使用量增長過快引發full GC。
class T33 extends Thread {
public void run() {
List<Map<String,String>> list = new ArrayList();
for(int i=0;i<99999999;i++){
Map<String,String> map = new HashMap<String,String>(5000);
map.put("aaa", "123");
list.add(map);
try {
if(list.size()==5000){
//Thread.sleep(300000);
list =new ArrayList();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(map);
}
}
}
class Test2 {
public static void main(String[] args) throws InterruptedException {
T33 t4 = new T33();
t4.start();
}
}
首先使用jps -l 或者 ps ef|grep java 查到進程,我這裏使用的是 jps -l。
找到了進程12829。
再用jstat -gc 查看垃圾回收
輸入jstat -gc 12829 300 20 ;這個命令的意思是打印12829垃圾回收過程20次,每300毫秒打印一次。
可以看到進程12829的Full GC還是很頻繁的餓,這是由於Minor GC的時候剩餘的對象太多,surviceor區域放不下後只好放到年老帶,導致年老帶增加的對象特別快。
再用jmap -histo:live 12829
可以看到HashMap的Node對象所佔內存特別多,基本可以認定是產生了比較大的HahMap導致的Full GC過快的。
我們還可以dump產生進程的快照文件,對着文件分析一下。
使用命令 jmap -dump:format=b,file=tiaoyoutest.txt 12829,其中tiaoyoutest.txt就是所產生的文件
再使用Jhat -J-Xmx512m 7000 tiaoyoutest.txt 。其中Xmx是制定啓動的內存大小,7000是啓動的端口號。輸入這個後我們就可以在瀏覽器中輸入:127.0.0.1:7000看到對堆文件的分析了,但是感覺沒有什麼用。要用專業的工具,比如Meta。
我這裏是在mac上操作的,它不需要我輸入端口號,如果輸入端口號還有問題
再到瀏覽器裏輸入127.0.0.1:7000