Android-GC原理探究(深度好文)

2.1 java堆

Java堆实际上是由一个Active堆和一个Zygote堆组成的,其中,Zygote堆用来管理Zygote进程在启动过程中预加载和创建的各种对象,而Active堆是在Zygote进程fork第一个子进程之前创建的。以后启动的所有应用程序进程是被Zygote进程fork出来的,并都持有一个自己的Dalvik虚拟机。在创 《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》无偿开源 徽信搜索公众号【编程进阶路】 建应用程序的过程中,Dalvik虚拟机采用COW策略复制Zygote进程的地址空间。

COW策略:一开始的时候(未复制Zygote进程的地址空间的时候),应用程序进程和Zygote进程共享了同一个用来分配对象的堆。当Zygote进程或者应用程序进程对该堆进行写操作时,内核就会执行真正的拷贝操作,使得Zygote进程和应用程序进程分别拥有自己的一份拷贝,这就是所谓的COW。因为copy是十分耗时的,所以必须尽量避免copy或者尽量少的copy。

为了实现这个目的,当创建第一个应用程序进程时,会将已经使用了的那部分堆内存划分为一部分,还没有使用的堆内存划分为另外一部分。前者就称为Zygote堆,后者就称为Active堆。这样只需把zygote堆中的内容复制给应用程序进程就可以了。以后无论是Zygote进程,还是应用程序进程,当它们需要分配对象的时候,都在Active堆上进行。这样就可以使得Zygote堆尽可能少地被执行写操作,因而就可以减少执行写时拷贝的操作。在Zygote堆里面分配的对象其实主要就是Zygote进程在启动过程中预加载的类、资源和对象了。这意味着这些预加载的类、资源和对象可以在Zygote进程和应用程序进程中做到长期共享。这样既能减少拷贝操作,还能减少对内存的需求。

2.2 和GC有关的一些指标

记得我们之前在优化魅族某手机的gc卡顿问题时,发现他很容易触发GC_FOR_MALLOC,这个GC类别后续会说到,是分配对象内存不足时导致的。可是我们又设置了很大的堆Size为什么还会内存不够呢,这里需要了解以下几个概念:分别是Java堆的起始大小(Starting Size)、最大值(Maximum Size)和增长上限值(Growth Limit)。

在启动Dalvik虚拟机的时候,我们可以分别通过-Xms、-Xmx和-XX:HeapGrowthLimit三个选项来指定上述三个值,以上三个值分别表示表示

Starting Size : Dalvik虚拟机启动的时候,会先分配一块初始的堆内存给虚拟机使用。

Growth Limit:是系统给每一个程序的最大堆上限,超过这个上限,程序就会OOM

Maximum Size:不受控

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值