码迷,mamicode.com
首页 > 其他好文 > 详细

使用jprofile发现和修复内存泄露

时间:2015-05-12 10:48:27      阅读:110      评论:0      收藏:0      [点我收藏+]

标签:

性能分析有一项是:发生OOM时,浏览对象分配和引用以发现和修复内存泄露;

示例程序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

 

运行PointFactory;

技术分享

运行jprofile,选择本地jvm;

技术分享

选择程序;

技术分享

来了个很恐怖的警告:

技术分享

某些情况下,在attach mode下有一个bug会导致jvm崩溃;

Sun JVM Attach API是Sun JVM中的一套非标准的可以连接到JVM上的API;

Bug详情:

  • Sun Java (HotSpot) client JVM can crash in attach mode due to a JVM bug
    Due to a JVM bug 6776659 HotSpot client JVM can crash in attach mode.
    There is no crash for the server JVM: JVM option -server solves the problem.

源文档 <https://www.yourkit.com/docs/java/help/attach_agent.jsp>

咱还是听话运行在server mode吧;

技术分享

这次就没提示了;

选择

技术分享

选择instrumentation仪表盘,我们要看所有的分析;

技术分享

这么多类咋看嘛,怀疑Point类存在内存泄露,那就只看它了,设置View Filters;

技术分享

这时候还没有点按钮,所以没有创建一个类;点!

技术分享

技术分享

但是视图里边还是空啊;

得用java.awt.Point,幸好我够机智;

技术分享

为啥5个类出来total是333?

再点一次,变成418;

技术分享

点击垃圾回收Run GC:

技术分享

剩10个实例,正常了;本应10个实例,为什么会有418个那么多;

以此类推,点按钮,Run GC,然后total每点一次增加5个,证明了Point类是回收不掉的;

已经集成到eclipse的话,可以Profile As Java application,很方便;

技术分享

那为啥Point类没释放呢?明明它已经没用了;

实际项目中,找源代码然后逐个找引用会累死人,咱还是通过运行时堆栈的快照来看吧;

切换到Heap视图;

技术分享

在累计引用列表可以看到谁引用了Point;

技术分享

这里是points这个Arraylist引用了,但是没有移除导致;

使用完之后调用removePoint就可以了。

使用jprofile发现和修复内存泄露

标签:

原文地址:http://www.cnblogs.com/yejq/p/4496395.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!