Android性能优化之内存抖动分析

内存抖动产生的原因
内存抖动是由于短时间内有大量对象进出新生区导致的,它伴随着频繁的GC。
gc会大量占用ui线程和cpu资源,会导致app整体卡顿。内存频繁的分配与回收,(分配速度大于回收速度时)最终会产生OOM。
在这里插入图片描述
内存回收算法
1、标记清除算法Mark-Sweep
在这里插入图片描述2、复制算法Copying
在这里插入图片描述3、标记压缩算法Mark-Compact
在这里插入图片描述4、分代收集算法
Permanent和垃圾回收没什么关系,主要用来存放类,方法信息,也能作为常量沲使用,不同VM不同实现,有些没这个区
在这里插入图片描述

  • Serial串行收集器
    在这里插入图片描述
  • ParNew 收集器
    在这里插入图片描述
  • Parallel Scavenge收集器
    吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)。
    在这里插入图片描述
  • Serial Old收集器
    在这里插入图片描述
  • Parallel Old收集器
    在这里插入图片描述
  • CMS 收集器
    CMS采用"标记-清理"算法实现以获取最短回收停顿时间为目标的收集器
    初始标记:标记一下GC Roots能直接关联到的对象
    并发标记:进行GC Roots Tracing 的过程
    重新标记:是为了修正并发标记期间因用户程序继续运行而导致标记产品变动的那一部分对象的标记记录
    并发清除:清除不能到达GC Roots的对象 
    重置线程:更新之前使用过的数据

内存抖动的实例

public class MainActivity extends AppCompatActivity {

    private static Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            // 创造内存抖动
            for (int index = 0; index <= 100; index++) {
                String arg[] = new String[10000];
            }
            mHandler.sendEmptyMessageDelayed(0, 1000);
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        mHandler.removeCallbacksAndMessages(null);
    }
    public void onMemoryJitter(View view) {
        mHandler.sendEmptyMessage(0);
    }
}

如上代码所示,在点击按钮的时候,每隔一秒钟就创建一个String数组,里面存放10000个元素。我们频繁的这样创建会内存泄漏,就会导致系统GC回收内存。

内存抖动日志分析如下所示:

2020-05-15 21:00:24.643 6632-6647/com.wq.demo E/com.wq.demo: GcSupervisor: GC congestion PID:6632 Freq:21/1.090s
2020-05-15 21:00:25.685 6632-6647/com.wq.demo E/com.wq.demo: GcSupervisor: GC congestion PID:6632 Freq:21/1.041s
2020-05-15 21:00:26.750 6632-6647/com.wq.demo E/com.wq.demo: GcSupervisor: GC congestion PID:6632 Freq:21/1.064s
2020-05-15 21:00:27.837 6632-6647/com.wq.demo E/com.wq.demo: GcSupervisor: GC congestion PID:6632 Freq:21/1.086s
2020-05-15 21:00:29.143 6632-6647/com.wq.demo E/com.wq.demo: GcSupervisor: GC congestion PID:6632 Freq:21/1.135s
2020-05-15 21:00:30.196 6632-6647/com.wq.demo E/com.wq.demo: GcSupervisor: GC congestion PID:6632 Freq:21/1.052s
2020-05-15 21:00:31.189 6632-6647/com.wq.demo E/com.wq.demo: GcSupervisor: GC congestion PID:6632 Freq:21/992.157ms
2020-05-15 21:00:32.147 6632-6647/com.wq.demo E/com.wq.demo: GcSupervisor: GC congestion PID:6632 Freq:21/957.596ms
2020-05-15 21:00:33.183 6632-6647/com.wq.demo E/com.wq.demo: GcSupervisor: GC congestion PID:6632 Freq:21/1.035s

android profile 效果图如下图
Memory 中
在这里插入图片描述我们可以看到 上面的一个白色垃圾桶。说明在大量的执行gc操作。用了一会儿 手机就开始卡了
快速定位内存抖动
在这里插入图片描述如上图所示,我们找到我们的应用就可以快速定位出代码中出现内存抖动的位置。

避免发生内存抖动的几点建议:

  • 尽量避免在循环体内创建对象,应该把对象创建移到循环体外
  • 注意自定义View的onDraw()方法会被频繁调用,所以在这里面不应该频繁的创建对象
  • 当需要大量使用Bitmap的时候,试着把它们缓存在数组中实现复用。
  • 对于能够复用的对象,同理可以使用对象池将它们缓存起来

总之,因为内存抖动是由于大量对象在短时间内被配置而引起的,所以我们要做的就是谨慎对待那些可能会大量创建对象的情况。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值