首页 > 编程语言 > 详细

JVM-垃圾收集算法

时间:2021-04-06 23:20:34      阅读:30      评论:0      收藏:0      [点我收藏+]

 

如何判断Java对象是否已死?

引用计数法、可达性算法。

引用计数法?

1. 描述

每个对象有一个引用计数器,当对象被引用一次则计数器加1,当对象引用失效一次则计数器减1,对于计数器为0的对象意味着是垃圾对象,可以被GC回收。

2. 优点

  • 判断方式简单。
  • 算法效率高。

3. 缺点

  • 循环引用。

可达性算法?

1. 描述

从GC Roots对象作为起始点,利用数学中图论知识,图中可达对象便是存活对象,而不可达对象则是需要回收的垃圾内存。

技术分享图片

GC Roots对象包括:

  • 虚拟机栈中引用的对象。
  • ?法区中类静态变量和常量引用的对象。
  • 本地?法栈中的JNI所引用的对象。

 

垃圾收集算法

标记清除算法、复制算法、标记整理算法、分代收集算法

标记清除算法

分为两个阶段:标记、清除

标记阶段:确定所有需要回收的对象,并做好标记。

清除阶段:将标记阶段确认不可用的对象清除。

缺点:

1. 标记和清除的效率都不高。

2. 会产生大量不连续的内存碎片,空间碎片过多可能导致以后在程序运行过程中需要分配较大对象时,无法为其分配足够大的连续空间,导致不得不提前进行一次垃圾回收。

复制算法

内存分为两块大小相同的区域,每次只使用其中一块。当垃圾回收时,把存活的对象复制到另一块上,然后把这块内存整个清理掉。交换两个内存的角色,完成垃圾回收。

缺点

1. 需要浪费额外的空间作为复制区。

2. 不适用于存活对象较多的场合,如老年代。当对象的存活率较高时,复制算法效率会下降。

标记整理算法

先标记出所有存活的对象,把存活的对象往一端移动,然后直接回收边界外的空间。

特点

适用于存活对象较多的场合,如老年代。

三种算法比较

效率:复制 > 标记整理 > 标记清除(此处的效率只是简单的对比时间复杂度,实际情况并非如此)

内存利用率:标记整理 > 标记清除 > 复制

内存整齐度: 复制 = 标记整理 > 标记清除

分代收集算法

分代收集算法根据对象的存活时间把内存分为新生代老年代。 根据分代对象的特点,每个代使用不同的垃圾回收算法。

新生代:每次垃圾回收都会有大量对象死去,只有少量存活,因此选择复制算法

老年代:因为对象存活率高、没有额外空间为他们进行分配担保,因此选择标记-清除标记-整理算法。

技术分享图片

 

新生代Young:存放新创建的对象,对象的生命周期非常短,几乎用完就可以回收,也叫eden区。

老年代Old:young区多次回收后存活下来的对象将被移进Old区。

永久代Permanent:主要存储加载的类信息,生命周期长,几乎不会被回收。

 

老年代 + 永久代 约占堆的2/3,新生代约占堆的1/3。

新生代又被分为eden、from survivor、to survivor(8:1:1)。JVM每次都只使用eden和其中一块survivor来为对象进行服务,所以无论什么时候,都会有一块survivor空间,因此新生代实际可用空间为90%。

当对象在eden中创建,经历过一次minor gc后仍然存活,并且能够被to survivor所容纳,则使用复制算法将这些存活的对象复制到to survivor区,然后清理掉eden和from survivor区,并将这些存活的对象年龄+1,以后对象在survivor每熬过一次minor gc,年龄便+1,当对象达到某个值时(默认为15,通过设置参数-xx:maxtenuringThreshold来设置),这些对象就会被移动到老年代。当一些较大的对象(需要分配连续的内存空间)则直接进入老年代。

JVM-垃圾收集算法

原文:https://www.cnblogs.com/th2009yu/p/14564364.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!