性能分析有一項(xiàng)是:發(fā)生OOM時(shí),瀏覽對(duì)象分配和引用以發(fā)現(xiàn)和修復(fù)內(nèi)存泄露;
示例程序PointFactory

public class PointFactory { protected ArrayList points = new ArrayList(); protected static PointFactory instance = new PointFactory(); public Point createPoint(int x, int y) { Point point = new Point(x, y); this.points.add(point); return point; } public void removePoint(Point point) { this.points.remove(point); } public void printTestPoints() { for (int i = 0; i < 5; i++) { Point point = createPoint(i, i); System.out.println("Point = " + point); } } public static PointFactory getInstance() { return instance; } public static void main(String[] args) throws Exception { JFrame frame = new JFrame("Points Test"); frame.setDefaultCloSEOperation(WindowConstants.EXIT_ON_CLOSE); JButton button = new JButton("Print Test Points"); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { PointFactory.getInstance().printTestPoints(); } }); frame.getContentPane().add(button); frame.setSize(200, 100); frame.setVisible(true); }}View Code運(yùn)行PointFactory;
![clip_image001[8] clip_image001[8]](http://s1.VeVb.com/20150728/je3tfih3skx16.png)
運(yùn)行jprofile,選擇本地jvm;
![clip_image002[5] clip_image002[5]](http://s1.VeVb.com/20150728/niamn5xnero16.png)
選擇程序;
![clip_image003[4] clip_image003[4]](http://s1.VeVb.com/20150728/bucswtb31i116.png)
來了個(gè)很恐怖的警告:
![clip_image004[4] clip_image004[4]](http://s1.VeVb.com/20150728/hwzozl3pl1j16.png)
某些情況下,在attach mode下有一個(gè)bug會(huì)導(dǎo)致jvm崩潰;
Sun JVM Attach API是Sun JVM中的一套非標(biāo)準(zhǔn)的可以連接到JVM上的API;
Bug詳情:
源文檔 <https://www.yourkit.com/docs/java/help/attach_agent.jsp>
咱還是聽話運(yùn)行在server mode吧;
![clip_image005[4] clip_image005[4]](http://s1.VeVb.com/20150728/dflcdwzczgd16.png)
這次就沒提示了;
選擇
![clip_image006[4] clip_image006[4]](http://s1.VeVb.com/20150728/moclwn2fxyl16.png)
選擇instrumentation儀表盤,我們要看所有的分析;
![clip_image007[4] clip_image007[4]](http://s1.VeVb.com/20150728/zipomscfgol16.png)
這么多類咋看嘛,懷疑Point類存在內(nèi)存泄露,那就只看它了,設(shè)置View Filters;
![clip_image008[4] clip_image008[4]](http://s1.VeVb.com/20150728/ahezcf5ssop16.png)
這時(shí)候還沒有點(diǎn)按鈕,所以沒有創(chuàng)建一個(gè)類;點(diǎn)!
![clip_image009[4] clip_image009[4]](http://s1.VeVb.com/20150728/e1jdnvyuovg16.png)
![clip_image010[4] clip_image010[4]](http://s1.VeVb.com/20150728/wg23tsom3bc17.png)
但是視圖里邊還是空啊;
得用java.awt.Point,幸好我夠機(jī)智;
![clip_image011[4] clip_image011[4]](http://s1.VeVb.com/20150728/mkwu3b3yho117.png)
為啥5個(gè)類出來total是333?
再點(diǎn)一次,變成418;
![clip_image012[4] clip_image012[4]](http://s1.VeVb.com/20150728/544trhxatnt17.png)
點(diǎn)擊垃圾回收Run GC:
![clip_image013[4] clip_image013[4]](http://s1.VeVb.com/20150728/w4vcpox2wpn17.png)
剩10個(gè)實(shí)例,正常了;本應(yīng)10個(gè)實(shí)例,為什么會(huì)有418個(gè)那么多;
以此類推,點(diǎn)按鈕,Run GC,然后total每點(diǎn)一次增加5個(gè),證明了Point類是回收不掉的;
已經(jīng)集成到eclipse的話,可以Profile As Java application,很方便;
![clip_image014[4] clip_image014[4]](http://s1.VeVb.com/20150728/od1122r1csd17.png)
那為啥Point類沒釋放呢?明明它已經(jīng)沒用了;
實(shí)際項(xiàng)目中,找源代碼然后逐個(gè)找引用會(huì)累死人,咱還是通過運(yùn)行時(shí)堆棧的快照來看吧;
切換到Heap視圖;
![clip_image015[6] clip_image015[6]](http://s1.VeVb.com/20150728/q1q3suczoef17.png)
在累計(jì)引用列表可以看到誰引用了Point;
![clip_image015[7] clip_image015[7]](http://s1.VeVb.com/20150728/i5dx2wqp4ap17.png)
這里是points這個(gè)Arraylist引用了,但是沒有移除導(dǎo)致;
使用完之后調(diào)用removePoint就可以了。
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注