欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

如何使用Memory Analyzer(Mat)检测内存泄漏

程序员文章站 2024-03-21 17:03:22
...

一、下载安装Memory Analyzer (MAT) https://www.eclipse.org/mat/

二、准备内存泄漏示例app,核心代码如下(Kotlin),安装运行它

class MainActivity : Activity(), CallBack {
    private val imageView by lazy { findViewById<ImageView>(R.id.iv_memoryLeak) }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val bitmap: Bitmap = BitmapFactory.decodeResource(resources, R.drawable.avatar)
        imageView.setImageBitmap(bitmap)

        CallBackManager.addCallBack(this)
    }

    override fun onDestroy() {
        super.onDestroy()
//        CallBackManager.removeCallBack(this)  //去掉此行,反复进出activity会导致内存泄漏
    }

    override fun doOperate() {
        //do sth
    }
}

interface CallBack {
    fun doOperate()
}

object CallBackManager {
    private val sCallBacks = ArrayList<CallBack>()

    fun addCallBack(callBack: CallBack) {
        sCallBacks.add(callBack)
    }

    fun removeCallBack(callBack: CallBack) {
        sCallBacks.remove(callBack)
    }
}

三、打开AndroidStudio 打开Profiler分析内存泄漏,session上添加该app的任务,

1.点击memory(此时内存只有17.6M)

如何使用Memory Analyzer(Mat)检测内存泄漏

2.连续操作,发现内存不断飙升

如何使用Memory Analyzer(Mat)检测内存泄漏

3.点击触发强制GC的按钮,内存并没有下降

如何使用Memory Analyzer(Mat)检测内存泄漏

4.点击dump java heap,抓取堆内存;弹出选项框选择Yes

如何使用Memory Analyzer(Mat)检测内存泄漏

如何使用Memory Analyzer(Mat)检测内存泄漏

5.点击保存按钮,保存为hprof文件如何使用Memory Analyzer(Mat)检测内存泄漏

 

四、利用Android SDK的工具hprof-conv.exe对刚才的.hprof文件做一个转换

1.找到hprof-conv.exe所在目录D:\Sdk\platform-tools

2.右键Git Bash Here,输入命令行

如何使用Memory Analyzer(Mat)检测内存泄漏

如何使用Memory Analyzer(Mat)检测内存泄漏

五、使用安装好的Eclipse Memory Analyzer打开刚才转换后的.hprof文件

1.点击Histogram按钮

如何使用Memory Analyzer(Mat)检测内存泄漏

2.在弹出的Histogram列表中,搜索可能产生内存泄漏的MainActivity

如何使用Memory Analyzer(Mat)检测内存泄漏

3.选择第一个MainActivity,右键Merge Shortest Paths to GC Roots-->选择exclude weak/soft references(筛除弱引用和软引用),留下的就是内存泄漏的引用

如何使用Memory Analyzer(Mat)检测内存泄漏

 

六、Mat的高级用法

1.点击分组按钮(选择Group by Package),可以通过包名找到 各自包名下的实例引用。(如可以直接搜索当前项目包名,快速定位内存泄漏位置)

如何使用Memory Analyzer(Mat)检测内存泄漏

2.打开dominator_tree(直接分析占用内存大的实例)

当前内存泄漏,虽然是activity内存泄漏,但是activity中占有内存最大的是Bitmap

如何使用Memory Analyzer(Mat)检测内存泄漏如何使用Memory Analyzer(Mat)检测内存泄漏

3.检索数据库,查找类的实例

如何使用Memory Analyzer(Mat)检测内存泄漏

4.Top Components:找到占用内存大的实例,和该实例的引用堆栈

5.Leak Suspects:直接找到内存泄漏的对象,和引用堆栈

如何使用Memory Analyzer(Mat)检测内存泄漏