1.什么是内存泄漏?
内存泄漏就是:一个对象不再被使用了,但是它又直接或者间接的被 GC-root对象引用着,这就是内存泄漏。
2.什么是GC-root对象?
GC-root对象就是永远不会被GC回收的对象。 比如静态变量,类对象,方法名,栈区对象。
举个例子:
先编写一个单例内存泄漏的例子:
编写一个单例类:
public class Instance { private static Instance instance; Context mContext; private Instance(Context context) { mContext = context; } public static Instance getInstace(Context context) { if (instance == null) { instance = new Instance(context); } return instance; } }
然后在一个activity里获取这个单例对象
public class OneActivity extends Activity { @Override protected void onCreate( Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.ativity_one); Instance.getInstace(OneActivity.this); } }
使用android studio profiler运行程序之后,打开这个OneActivity,然后再关闭,再打开,,再关闭。
然后点击profiler的GC回收按钮。如果是android studio 3.0以上版本的,找不到GC按钮的可以看下面:
鼠标放在CPU上,然后右键选择Open CPU, 然后选择Memory
然后就可以看到GC按钮了:
点击GC之后:点击 GC旁边这个按钮,就会生成一个Heap Dump的选择在左边。
然后点击Export Heap Dump 这个按钮保存文件,文件保存路径是在android sdk 的\platform-tools下面的
到这里有内存溢出的文件就被我们保存了。
我们要做的就是把这个memory-20190722T112226.phrof文件 利用E:\Android\Sdk\platform-tools下的hprof-conv程序转成mat可以打开的文件。
打开命令行:cd 到E:\Android\Sdk\platform-tools路径下
然后键入:hprof-conv befor.hprof after.hprof 然后回车
befor.hprof是在android studio GC之后保存到E:\Android\Sdk\platform-tools下的文件。after.hprof是回车之后生成的文件。
然后在mat下File→Open file→打开after.hprof文件
选择:Leak Suspects Repot 点击完成
然后选择Create a this histogram from an按钮
之后
键入OneActivity回车
鼠标放在这右键:选择Merge Shortest Paths to GC Roots → exclude all phantom/weak/soft etc.references 过滤掉不能被GC的文件
这样就可以看到mContext对象被instance对象引用着。导致mContext不能被GC回收,引发内存泄漏。
引发内存泄漏的不止是单例,其他的还有很多,Handler 线程 内部类等 都有可能会引发内存泄漏。