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

性能分析有一项是:发生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);
    }

}

运行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就可以了。

时间: 2024-08-22 05:04:15

使用jprofile发现和修复内存泄露的相关文章

查找并修复Android中的内存泄露—OutOfMemoryError

[编者按]本文作者为来自南非约翰内斯堡的女程序员 Rebecca Franks,Rebecca 热衷于安卓开发,拥有4年安卓应用开发经验.有点完美主义者,喜爱美食. 本文系国内ITOM管理平台 OneAPM 编译呈现,以下为正文. Android 程序中很容易出现内存泄露问题.毫无戒心的开发者可能每天都会造成一些内存泄露,却不自知.你可能从未注意过这类错误,或者甚至都不知道它们的存在.直到你遇到下面这样的异常: java.lang.OutOfMemoryError: Failed to allo

LeakCanary:检测所有的内存泄露

本文译自:https://corner.squareup.com/2015/05/leak-canary.html(LeakCanary是由Square公司刚刚开源用于查找Android内存泄露的库) java.lang.OutOfMemoryError at android.graphics.Bitmap.nativeCreate(Bitmap.java:-2) at android.graphics.Bitmap.createBitmap(Bitmap.java:689) at com.sq

在iOS上自动检测内存泄露

手机设备的内存是一个共享资源.应用程序可能会不当的耗尽内存.崩溃,或者遭遇大幅度的性能降低. Facebook iOS客户端有很多功能,并且它们共享同一块内存空间.如果任何特定的功能消耗过多的内存,就会影响到整个应用程序.这是可能发生的,比如,这个功能导致了内存泄露. 当我们分配了一块内存,并设置了对象之后,如果在使用完了之后忘记释放,这就会发生内存泄露.这意味着系统是无法回收内存并交予他人使用,这也最终意味着我们的内存将会逐渐耗尽. 在Facebook,我们有很多工程师在代码库的不同部分上工作

使用gc、objgraph干掉python内存泄露与循环引用!

Python使用引用计数和垃圾回收来做内存管理,前面也写过一遍文章<Python内存优化>,介绍了在python中,如何profile内存使用情况,并做出相应的优化.本文介绍两个更致命的问题:内存泄露与循环引用.内存泄露是让所有程序员都闻风丧胆的问题,轻则导致程序运行速度减慢,重则导致程序崩溃:而循环引用是使用了引用计数的数据结构.编程语言都需要解决的问题.本文揭晓这两个问题在python语言中是如何存在的,然后试图利用gc模块和objgraph来解决这两个问题. 注意:本文的目标是Cpyth

4类 JavaScript 内存泄露及如何避免

原文:4 Types of Memory Leaks in JavaScript and How to Get Rid Of Them笔记:涂鸦码龙 译者注:本文并没有逐字逐句的翻译,而是把我认为重要的信息做了翻译.如果您的英文熟练,可以直接阅读原文. 本文将探索常见的客户端 JavaScript 内存泄露,以及如何使用 Chrome 开发工具发现问题. 简介 内存泄露是每个开发者最终都要面对的问题,它是许多问题的根源:反应迟缓,崩溃,高延迟,以及其他应用问题. 什么是内存泄露? 本质上,内存泄

使用LeakCanary检测内存泄露 翻译

原文:https://academy.realm.io/cn/posts/droidcon-ricau-memory-leaks-leakcanary/ GitHub:https://github.com/square/leakcanary Nov 18 2015 目录 中文翻译介绍 (0:00)内存泄漏:非技术讲解 (1:40)LeakCanary 救援 (3:47)技术讲解内存泄漏 (8:06)分析堆 (10:16)LeakCanary 救你于水火 (12:04)LeakCanary API

[Android Memory] App调试内存泄露之Context篇(下)

转载地址:http://www.cnblogs.com/qianxudetianxia/p/3655475.html 5. AsyncTask对象 我N年前去盛大面过一次试,当时面试官极力推荐我使用AsyncTask等系统自带类去做事情,当然无可厚非. 但是AsyncTask确实需要额外注意一下.它的泄露原理和前面Handler,Thread泄露的原理差不多,它的生命周期和Activity不一定一致. 解决方案是:在activity退出的时候,终止AsyncTask中的后台任务. 但是,问题是如

linux下内存泄露检测工具Valgrind

日前在linux开发一个分析实时路况的应用程序,在联合测试中发现程序存在内存泄露的情况. 这下着急了,马上就要上线了,还好发现了一款Valgrind工具,完美的解决了内存泄露的问题. 推荐大家可以使用看看. Valgrind是运行在Linux上一套基于仿真技术的程序调试和分析工具,它的主要作者是获得过Google-O'Reilly开源大奖的Julian Seward,它包含一个内核──一个软件合成的CPU,和一系列的小工具,每个工具都可以完成一项任务──调试,分析,或测试等.Valgrind可以

Android开发过程中内存泄露检测

转自 http://blog.csdn.net/shimiso/article/details/44677041 一.内存泄露 内存泄漏会因为减少可用内存的数量从而降低计算机的性能.最终,在最糟糕的情况下,过多的可用内存被分配掉导致全部或部分设备停止正常工作,或者应用程序崩溃. 内存泄漏可能不严重,甚至能够被常规的手段检测出来.在现代操作系统中,一个应用程序使用的常规内存在程序终止时被释放.这表示一个短暂运行的应用程序中的内存泄漏不会导致严重后果. 在以下情况,内存泄漏导致较严重的后果: 1)程