性能优化系列——内存泄漏

前言

之前写了一篇《性能优化系列-内存抖动》简单实用Memory Profiler工具解决内存抖动的情况,这边文章写实用工具配合MAT解决内存泄漏。

内存泄漏介绍

  • 定义:内存中存在已经没有用的对象
  • 表现:内存泄漏引起,内存泄漏,可用内存逐渐减少,系统为了增加可用内存就会一直GC,导致内存抖动。
  • 危害: 内存不足、GC频繁、OOM

Memory Analyzer

  • Download
  • 转换HROF-ENV

内存泄漏用例

MemoryLeakActivity

class MemoryLeakActivity : AppCompatActivity(),ImageCallBack {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_memory_leak)
        var bitmap = BitmapFactory.decodeResource(resources,R.mipmap.splash)
        conent_iv.setImageBitmap(bitmap)
        CallBackManager.addCallBack(this)
    }

    override fun handleImage(url: String) {

    }
}

ImageCallBack

package com.martin.perfomance.memory

interface ImageCallBack {

    fun handleImage(url:String)

}

CallBackManager

object CallBackManager {

    var callBackList:MutableList<ImageCallBack> = mutableListOf()

    /**
     * 添加监听
     */
    fun addCallBack(callback:ImageCallBack){
        callBackList.add(callback)
    }

    /**
     * 移除监听
     */
    fun removeCallBack(callback: ImageCallBack){
        callBackList.remove(callback)
    }

}

内存泄漏解决实战

性能优化系列——内存泄漏_第1张图片
可以看见我们在频繁进入界面后,并没有释放当前的Activity。目前可以从图案中查看内存呈现梯形上升,表明我们创建的对象并没有被释放。那么我们如何进一步的分析是哪段代码导致这样的情况呢?
性能优化系列——内存泄漏_第2张图片性能优化系列——内存泄漏_第3张图片
通过上面的两步,我获得了hprof的内存快照,接下来我们MAT工具进行内存分析。

如果Mac上的独立版本无法打开文件可以参考《Mac Mat独立版本打开失败解决方案》

MAT查看Hprof的内存分布情况

进入/Users/martin/Library/Android/sdk/platform-tools使用命令,将刚生成的hprof文件进行转换。

hprof-conv /Users/martin/Workspace/memory-20200205T184519.hprof /Users/martin/Workspace/memory-leak_transed.hprof

使用mat打开查看图片
性能优化系列——内存泄漏_第4张图片
查看内存的分布情况:
性能优化系列——内存泄漏_第5张图片
从上面我们可以搜索对象在内存中的情况,这里我们搜索内存泄漏的对象MemoryLeakActivity
性能优化系列——内存泄漏_第6张图片
可以看见MemoryLeakActivity在内存中有4个对象,这是很不合理的。
我们可以通过右键可以查看当前对象被什么地方引用。

  • with outgoing references:被引用的地方
  • with incoming references:哪些强引用引向了我

然后我们查看GCRoot的路径,查询所有的引用。

可以看见,这里集合对象保存了我们的Activity对象,导致无法释放。
性能优化系列——内存泄漏_第7张图片

MAT工具详解

这里简单介绍一下MAT工具一些使用的功能,方便我们以后查看。
首先,我们需要查看下以包结构显示对象在内存中的情况,如图:
Histogram
性能优化系列——内存泄漏_第8张图片
性能优化系列——内存泄漏_第9张图片
domaintor_tree
从基于实例的角度,查看对象占用的百分比
性能优化系列——内存泄漏_第10张图片
Percentage:代表对象占用的百分比,上面可以看见图片所占内存比重较大,是内存的大头。
OQL
通过SQL语句查询对象
性能优化系列——内存泄漏_第11张图片
Top Consumer
查看对象在内存中的占用排行,对内存优化比较有帮助。
性能优化系列——内存泄漏_第12张图片
Leak Sespect
工具直接分写,内存泄漏的情况。
性能优化系列——内存泄漏_第13张图片

总结

回顾下上面的操作:

  • 通过Memory Profiler 去查看内存实用情况,并且将内存文件hrof进行转换。
  • 实用MAT工具分析分析hropf格式的文件。

你可能感兴趣的:(Android进阶知识)