内存泄漏
定义:内存中存在已经没有使用的对象
表现:内存抖动,可用内存逐渐变少
危害:内存不足,GC频繁,OOM
常见的内存泄漏的场景:
(1)静态变量导致的内存泄漏。
(2)单例模式导致的内存泄漏。
(3)属性动画导致的内存泄漏。
如何检测出内存泄漏
(1)先使用memory profiler 检测是否有内存阶梯状增长。
(2)导出heap文件
(3)使用MAT(memory analyze)
模拟内存泄漏的代码:
public interface CallBack {
void dpOperate();
}
public class CallBackManager {
public static ArrayList<CallBack> sCallBacks = new ArrayList<>();
public static void addCallBack(CallBack callBack) {
sCallBacks.add(callBack);
}
public static void removeCallBack(CallBack callBack) {
sCallBacks.remove(callBack);
}
}
/**
* 模拟内存泄露的Activity
*/
public class MemoryLeakActivity extends AppCompatActivity implements CallBack{
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_memoryleak);
ImageView imageView = findViewById(R.id.iv_memoryleak);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.splash);
imageView.setImageBitmap(bitmap);
CallBackManager.addCallBack(this);
}
// 下面的代码,模拟内存泄漏的时候,需要屏蔽掉。
@Override
protected void onDestroy() {
super.onDestroy();
CallBackManager.removeCallBack(this);
}
@Override
public void dpOperate() {
// do sth
}
}
步骤:
(1)先使用memory profiler 检测内存是否出现阶梯状,下面的图片:
(2)使用memory profiler导出java的heap文件,存在电脑中,使用 hprof-conv 命令转换。
使用的命令是: hprof-conv memory-20190503T191517.hprof memory-transed.hprof
(3)使用 MAT工具 打开hprof文件。
通过下图,可以找到对于包下的某个类的对象,可以发现对象数比较多的类。
或者使用下面的方法,先搜索 “memory” ,然后
注意区别:
(1)with outgoing references 我引用了哪些类
(2)with incoming references 我被哪些类引用。
在上图中,点击了 “with incoming references” 后,如下图所示。
再点击右键,并点击“with all references”,如下图,即可以看见调用关系: