经典垃圾收集器

学习深入理解Java虚拟机总结一下经典垃圾收集器的优缺点:

大多数对象是朝生夕死、熬过多次垃圾回收的对象就越难以消亡;Java虚拟机将堆划分区域,分配回收不同的区域新生代和老年代;新生代中对象存在大量要被回收的对象,老年代存在大量难以消亡的对象;然后出现对应不同区域的垃圾回收算法:标记-清除、标记-复制、标记-整理;

标记-清除算法:将需要回收的垃圾标记或将不需要回收的垃圾标记出来,然后依次清除掉垃圾对象。主要缺点是:执行效率不稳定,如果堆中存在大量的对象,标记和清除操作会因为对象的增加导致执行效率降低;内存碎片化,清除后没有对堆内存进行整理,导致内存中缺少连续的内存块,如果出现大对象的申请,会因为内存不足再次出发垃圾回收。

标记-复制算法:优化了标记清除算法的内存碎片化问题,将堆内存划分为两块内存,每次分配时只使用其中一块,在垃圾回收时,将存活的对象复制到另一块内存中,能够有效的避免内存碎片化。缺点是:存在大量存活的对象时,对象复制开销太大,而且浪费一部分内存。但是,如果内存块中存在大量消亡的对象时,标记-复制算法会比较简单,只需要移动堆顶指针就好;这块有一个有意思的问题是:为什么目前的垃圾收集器是一块Edgen和两块Surviror内存呢?标记-复制,是将A中存活的对象复制到内存B中,B和A的关系反转,B成为对象分配的内存,如果是5:5内存,那能够满足复制的要求,但浪费较多。如果是9:1,反转后内存只有1的成为被分配新对象的地址,岂不是直接就凉了。因此,一块Eden和两块Surviror,每次反转时,Eden是不变的,只有Surviror的关系是反转的,对象新建时每次都是在Eden中新生。

标记-整理算法:标记-复制算法因为存在大量存活对象时开销过大,不适合老年代。因此,标记-整理算法是将存活的对象移动到一侧,直接清理掉边界以外的内存。标记-整理和标记清除的差异是移动对象,而移动对象意味着栈中引用地址的变化,所以需要暂停应用程序操作(Stop the world),但是标记-清除又会出现大量的碎片化内存,针对新建对象的分配需要维持分区空闲分配链表来解决内存分配问题,导致频繁的内存申请又成为负担影响吞吐量。

Serial、ParNew、Parellel Scavenge都是采用标记复制的新生代垃圾收集器;

Serial:单线程,在进行垃圾收集时,必须暂停其他所有的线程,直到它收集结束;由于其他收集器的是:简单高效,对于内存受限的环境,是所有垃圾收集器中额外内存消耗最小的;客户端

ParNew:实质上是Serial的多线程并行版本,其他的特点与Serial一样,比如:Stop the Wrold、标记复制的算法等;服务端

Parellel Scavenge:其他收集器关注点是尽可能的缩短垃圾收集时用户的停顿时间,而Parellel Svavenge则关注的是用户线程的吞吐量,适用于后台运算而不需要太多交互的分析任务,而关注用户线程暂停时间的收集器则适用于交互场景。Parellel Scavenge提供了垃圾收集的自适应调节策略。

 

四款老年代的垃圾收集器:

Serial Old、Parellel Old、G1:标记-整理

CMS:标记-清除

Serial Old:是Serial的老年代收集器。单线程、Stop the World。与Serial不同的是采用标记-整理的算法;

Parellel Old:Parellel Scavenge的老年代收集器,强调吞吐量、多线程并行收集、Stop the World等

CMS:第一款做到与用户线程并发处理的垃圾收集器。以获取最短回收停顿时间为目标的收集器。

           1、初始标记:GC root到第一个对象的标记;Stop the World

           2、并发标记:与用户线程并发。开始遍历整个对象图,耗费时间长;Concurrent

           3、重新标记:修正并发标记期间,因用户线程导致标记变动的那部分对象;Stop the World

           4、并发清除:清除死亡对象,不需要改变存活对象的位置,所以与用户线程可以同时并发。Concurrent

         优点:耗费时间的并发标记和并发清除是可以与用户线程并发的,因此用户线程是短停顿的;

         缺点:在标记/清除垃圾对象时,与用户线程并发。线程间相互影响,对处理器资源非常敏感,而且处理不好容易导致吞吐量严重下降;采用的是标记-清除的算法,容易造成内存碎片化,容易造成在老年代存在空间却无法给对象分配内存,导致触发另外一次的Full GC;CMS的第二步是重新标记,但是不能处理此时并发线程申请的垃圾对象内存,需要预留部分内存地址供并发线程使用,当预留空间不足时,又会触发另一次的Full GC。

Garbage First(G1):面向全堆的垃圾收集器,没有固定的新生代、老年代,而是采用区域思想,每个区域可以作为新生代、老年代等不固定。垃圾回收时,不在衡量是新生代老年代,而是垃圾回收效率高就回收某个或多个区域。

      1、初始标记:GC root到第一个对象的标记;修改TAMS的指针的值(下一个阶段并发用户线程可以申请的用户区域) Stop the World

      2、并发标记:扫描整个堆的对象图。Concurrent

      3、最终标记:用于处理并发阶段结束后遗留下来的SATB记录。Stop the World

      4、筛选回收:将Region存活对象复制到空的Region中,清理掉整个旧的Region。涉及对象移动,必须暂停用户线程。Stop the World。

      G1的优点:用户指定期望停顿时间,设置不同的期望停顿时间,使得G1在不同场景中取得关注吞吐量和延迟间的平衡;G1优于CMS的是,G1采用标记整理算法,不存在碎片化内存,而CMS采用标记-清除造成碎片化内存;按收益来收集区域垃圾;G1解决跨代需要给每个区域都设有双向卡表,而CMS只有老年代到新生代的单向卡表,内存开销小。

 

内存分配策略:

1、对象优先在Eden区分配:当Eden区没有足够空间进行分配时(此处不是Eden和Surviror),虚拟机将发起一次Minr GC。如果将Eden+Surviror移动另一块Surviror时内存不够,会将Surviror无法放入的转移到老年代中

2、大对象直接进入老年代:特别长的字符串、大数组等,通过PretenureSizeThreshold参数设置阈值

3、长期存活的对象将进入老年代:默认为15

4、动态对象年龄判定:如果在Survivor空间中相同年龄对象大小总和大于Surviror空间的一半,年龄大于或等于该年龄的对象直接进入老年代

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值