Android 内存优化一 内存抖动的定位及优化

时间:2024-04-06 22:38:28

1 Android内存抖动

内存抖动是指内存忽高忽低,有短时间内快速的上升和下落的趋势,内存呈锯齿状。此时会频繁的GC,造成卡顿,甚至有OOM的可能
Android 内存优化一 内存抖动的定位及优化
内存抖动越剧烈,说明单次分配的内存更大。

2 内存抖动的定位

对于内存抖动的定位可直接使用Memory Profiler,原因是Memory Profiler可直接反应APP的内存占用,方便进行跟踪
发生内存抖动时,我们选择内存变化锯齿状的区域,然后在Memory Profiler可显示下面的图示
Android 内存优化一 内存抖动的定位及优化
接着我们点击Allocations进行对象分配数量排序,之所以点击这个是因为一般在循环,频繁调用的地方可能发生内存抖动
例如普通循环中,Adapter的get View或者onBinderView等方法中可能会发生内存抖动
所以如果发生了内存抖动,大概率的是在对象数量多的地方出现了问题,因此先进行对象数量排序
Android 内存优化一 内存抖动的定位及优化
到这里我们看到排在前几位的对象分别是Cleaner,NativeAllocationRegistry,Bitmap,Chat[],String等这几个对象。
Cleaner是垃圾回收相关的对象,NativeAllocationRegistry是内存分配相关的额对象,我们查看其调用栈如下:
Android 内存优化一 内存抖动的定位及优化
我们看到都和Bitmap创建相关,我们直接看Bitmap对象
Android 内存优化一 内存抖动的定位及优化
点击直接跳到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中对象的数量一定分配的比较多。当然还有一种内存抖动只有一个锯齿,这种情况可能是内存只分配了一个或者几个大的对象,这种情况通过对比锯齿前合锯齿上的内存分配也能对比出来

找到了内存抖动进行优化,一般来说就是避免在循环中创建内存抖动,可以使用对象复用等方式