垃圾收集算法 秒速五厘米 2022-06-04 05:24 252阅读 0赞 垃圾收集器与内存分配策略参考目录: > 1.[判断Java 对象实例是否死亡][Java] > 2.[ Java 中的四种引用][Java 1] > 3.[垃圾收集算法][Link 1] > 4.[ Java9中的GC 调优][Java9_GC] > 5.[内存分配与回收策略][Link 2] 这篇博文主要介绍虚拟机中的几种垃圾回收算法(当然进行垃圾回收的地方主要是指Java 堆)。 #### **标记 - 清除算法(Mark-Sweep)** #### 标记清除算法也是最基础的算法,和它的名字一样,在进行垃圾回收的时候主要分为“标记阶段” 和“清除阶段” : 首先标记出所需要回收的对象,在标记完成后进行统一回收所有被标记的对象。其他后面的几种算法都是在它的基础上对它做出的改进。标记清除算法在效率是上存在着一定的问题,原因是标记过程与清除过程的效率都不高;另外一方面是空间问题,原因是在标记清除之后会存在大量的不连续的内存碎片,这种情况导致在程序运行过程中分配大对象时因为无法找到连续的足够的内存空间不得不提前进行一次垃圾收集动作。 ![这里写图片描述][SouthEast] #### **复制算法(Coping)** #### 为了解决回收效率的问题,复制算法出现了。根据对象在Java 堆中创建的特点: 一般对象在新生代中分配内存,并且新生代中的对象98% 一般都是“朝生夕死” 的。根据这个特点将新生代划分成一块较大的Eden 区和两块小的Survivor(from 和 to) 区,每次使用Eden 和其中的一块Survivor 区。在进行垃圾回收时将Eden 区和一块Survivor 中还存活的对象一次性的复制到另一块Survivor 区上,然后清理掉刚才使用的Eden 区 和Survivor 区的内存空间。但是我们想在每次进行垃圾回收的时候不就有一块空间处于空闲状态了吗,这样不就使其中的一块Survivor 空间被浪费了吗?事实上Eden 区和Survivor 区的大小比例是8 : 1,也就是Eden 区占据了新生代中4/5 的内存空间,而两个Survivor 区只占到1/5 的内存空间。每次在进行垃圾回收的时候使用Eden 区 和其中的一块Survivor 区,那么就只有1/10 的空间被浪费,这点是可以接受的。但是我们也不能保证在进行垃圾回收之后另一块Survivor 区能够为所有存活下来的对象分配空间,当Survivor 空间不够用时这时就需要依赖其他的内存空间(老年代)进行分配担保。下面是复制算法过程示意图: ![这里写图片描述][SouthEast 1] 其中关于Eden 区域Survivor 区内存占比的问题我们可以通过打印GC 日志进行验证。这里我只拷贝了Java 堆中的内存放分配关系,我们可以看出新生代共有 38400K ,Eden 区占据了33280K,38400 - 33280 = 5120K。这5120K 就是两块Survivor区(其中一块叫from 区 一块叫 to 区,to 区就是在进行垃圾回收时空闲的一块,在一次回收完成时,from 区与to 区互换) 总共的内存大小,。通过打印结果看出它将两块Survivor 区的大小算在一起了,不要以为每一块Survivor 区都有5120K 空间的大小。下面就来计算一下Eden 区 是不是占了新生代总内存的4/5,通过33280 / 38400 = 86.7%,事实上比80% 的内存空间还要大一些,博主的jdk 是1.8,不知道是不是这个缘故,不过也没有没有关系啦,你只要能理解在使用复制算法进行垃圾回收的时候并没有很大的内存空间被浪费就好了。 Heap PSYoungGen total 38400K, used 998K [0x00000000d5f00000, 0x00000000d8980000, 0x0000000100000000) eden space 33280K, 3% used [0x00000000d5f00000,0x00000000d5ff9b20,0x00000000d7f80000) from space 5120K, 0% used [0x00000000d7f80000,0x00000000d7f80000,0x00000000d8480000) to space 5120K, 0% used [0x00000000d8480000,0x00000000d8480000,0x00000000d8980000) ParOldGen total 87552K, used 4705K [0x0000000081c00000, 0x0000000087180000, 0x00000000d5f00000) object space 87552K, 5% used [0x0000000081c00000,0x0000000082098400,0x0000000087180000) #### **标记-整理算法(Mark - Compat)** #### 通过上面了解我们可以知道使用复制算法时确实效果比标记-清除算法好很多,但是它也有一些局限,就是当处理一些存活率较高的对象时它的效率就会受到影响,当Survivor 区内存不够时就会在老年代上进行内存分配,所以可见对老年代进行必要的垃圾回收也是很重要的。根据老年代的点有人提出了一种“标记-整理”的 算法机制,标记的过程与“标记-清除”算法中实现的过程一样,但是后面的步骤不是对可回收对象进行清除而是让所有存活的对象向某一端移动,然后直接清理掉端边界以外的内存。 ![这里写图片描述][SouthEast 2] #### **分代收集算法(Generational Collection)** #### 其实这种算法并没有什么其他特别的地方,只是根据对象的存活周期将内存划分为几块。一般还是划分为新生代和老年代,然后根据各个区的特点选择适当的垃圾回收算法进行垃圾回收。由于新生代每次进行垃圾回收的时候都会有大批的对象死去,所以就使用“复制算法”。根据老年代对象存活时间长的特点就必须使用“标记-整理”和“标记-清除”算法进行垃圾回收。 本篇博文中的有关垃圾回收的相关图片均来自[天使的翅膀][Link 3]这位朋友,感谢! **参考书籍:** **《深入理解Java 虚拟机》周志明 著** [Java]: http://blog.csdn.net/codejas/article/details/78663217 [Java 1]: http://blog.csdn.net/codejas/article/details/78716533 [Link 1]: http://blog.csdn.net/codejas/article/details/78721517 [Java9_GC]: http://blog.csdn.net/codejas/article/details/78726909 [Link 2]: http://blog.csdn.net/codejas/article/details/78752825 [SouthEast]: /images/20220604/710f1eb4160346baa1e750ac3a90450a.png [SouthEast 1]: /images/20220604/547c7dfd79d14181af36d6de189b21da.png [SouthEast 2]: /images/20220604/0cb7209912c74fe0892f567f8760758a.png [Link 3]: http://www.cnblogs.com/zhuyuewei/p/7263735.html
相关 垃圾收集算法 一、新生代和老年代 新生代:主要存放新创建的对象,内存大小相对比较小,垃圾回收频繁。 老年代:存放生命周期比较长的对象,内存大小相对比较大,垃圾回收也没有那么频。 两 灰太狼/ 2023年10月01日 21:12/ 0 赞/ 32 阅读
相关 垃圾收集算法 标记-清除算法 Mark-Sweep 首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。 由两个不足: 1. 效率问题 今天药忘吃喽~/ 2023年07月04日 04:52/ 0 赞/ 51 阅读
相关 垃圾收集算法 对象已死吗 引用计数法 > 给对象中添加一个引用计数器,每当一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时刻计数器为0的对象就是不可能再被使 喜欢ヅ旅行/ 2023年06月03日 12:59/ 0 赞/ 56 阅读
相关 垃圾收集算法 1.标记-清除算法 标记处所有需要回收的对象,标记完成之后统一回收所有被标记的对象 不足之处:效率问题,标记和清除两个过程的效率都不高,空间问题:会产生很多内存碎片,以后在 ╰半橙微兮°/ 2023年03月12日 09:19/ 0 赞/ 44 阅读
相关 垃圾收集算法 垃圾收集器与内存分配策略参考目录: > 1.[判断Java 对象实例是否死亡][Java] > 2.[ Java 中的四种引用][Java 1] > 3.[垃圾收集算 秒速五厘米/ 2022年06月04日 05:24/ 0 赞/ 253 阅读
相关 垃圾收集算法 由于垃圾算法的实现涉及大量程序细节,而且各个平台的虚拟机操作内存的方法又各不相同,因此我们不需要过多关注算法的实现。只需要了解算法的思想和发展 1、标记-删除算法 ![ 深碍√TFBOYSˉ_/ 2022年05月14日 14:23/ 0 赞/ 263 阅读
相关 垃圾收集算法 垃圾收集算法 标记-清除算法 复制算法 标记-整理算法 分代收集算法 标记-清除算法 最基础的收集算法是“标 r囧r小猫/ 2022年03月10日 13:19/ 0 赞/ 298 阅读
相关 垃圾收集算法 标记-清除算法 其他算法的基础 主要问题: 1、效率低 2、造成大量内存碎片 复制算法 为了解决标记-清除算法的缺陷,将内存开成两个相等区域,对象动态 ╰+哭是因爲堅強的太久メ/ 2022年02月01日 07:45/ 0 赞/ 295 阅读
相关 垃圾收集算法 垃圾收集算法 标记-清除算法 复制算法 标记-整理算法 分代收集算法 标记-清除算法 最基础的收集算法是“标记-清除“算法,算法分为“标记 - 日理万妓/ 2021年09月24日 01:20/ 0 赞/ 349 阅读
相关 垃圾收集算法 由于垃圾收集算法的实现涉及大量的程序细节,而且各个平台的虚拟机操作内存的方法又各不相同,因此本节不打算过多地讨论算法的实现,只是介绍几种算法的思想及其发展过程。 小灰灰/ 2020年05月14日 16:09/ 0 赞/ 838 阅读
还没有评论,来说两句吧...