1 Android内存抖动
内存抖动是指内存忽高忽低,有短时间内快速的上升和下落的趋势,内存呈锯齿状。此时会频繁的GC,造成卡顿,甚至有OOM的可能
内存抖动越剧烈,说明单次分配的内存更大。
2 内存抖动的定位
对于内存抖动的定位可直接使用Memory Profiler,原因是Memory Profiler可直接反应APP的内存占用,方便进行跟踪
发生内存抖动时,我们选择内存变化锯齿状的区域,然后在Memory Profiler可显示下面的图示
接着我们点击Allocations进行对象分配数量排序,之所以点击这个是因为一般在循环,频繁调用的地方可能发生内存抖动
例如普通循环中,Adapter的get View或者onBinderView等方法中可能会发生内存抖动
所以如果发生了内存抖动,大概率的是在对象数量多的地方出现了问题,因此先进行对象数量排序
到这里我们看到排在前几位的对象分别是Cleaner,NativeAllocationRegistry,Bitmap,Chat[],String等这几个对象。
Cleaner是垃圾回收相关的对象,NativeAllocationRegistry是内存分配相关的额对象,我们查看其调用栈如下:
我们看到都和Bitmap创建相关,我们直接看Bitmap对象
点击直接跳到Bitmap创建的地方,如下:
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case MSG_MEMORY_JITTER:
for (int i = 0;i < 500;i++){
Bitmap bitmap = Bitmap.createBitmap(1920,1080, Bitmap.Config.ARGB_8888);
}
mHandler.sendEmptyMessageDelayed(MSG_MEMORY_JITTER,20);
break;
default:
break;
}
}
};
这里看到是一个循环,并且会重复调用,因此会产生内存抖动,这样就定位到了内存抖动的地方
3 内存抖动的优化
前面的例子为了看到效果,所以举了一个Bitmap的例子,并且分配的内存也比较大。在实际的开发中内存抖动的幅度可能比较小,也可能由于项目复杂,对象数量很多,所以定位起来不是那么的迅速,不过定位的思路应该是一致的,那就是内存抖动时APP中对象的数量一定分配的比较多。当然还有一种内存抖动只有一个锯齿,这种情况可能是内存只分配了一个或者几个大的对象,这种情况通过对比锯齿前合锯齿上的内存分配也能对比出来
找到了内存抖动进行优化,一般来说就是避免在循环中创建内存抖动,可以使用对象复用等方式