前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >4种回收算法

4种回收算法

原创
作者头像
Get
发布2024-03-20 21:26:03
1040
发布2024-03-20 21:26:03

标记-清除算法(Mark-Sweep) 

代码语言:java
复制
标记-清除:采用从根集合(GC Roots)进行扫描,对存活的对象进行标记,标记完毕后,再扫描整个空间中未被标记的对象,进行回收。
优点:
    效率高:是指清除阶段不是把未被标记的对象内存直接清空置为0,而是直接将这段内存从占用状态改成可用状态,下次需要使用时直接覆盖就可以了。
缺点:
    容易产生空间(内存)碎片:经过标记-清除算法的堆内存空间,可用的区域根本就不连续,
                          可能会导致后续过程中需要为大对象分配空间时无法找到足够的空间而提前触发新的一次垃圾收集动作。  

标记-整理算法(Mark-Compact):

代码语言:java
复制
标记-整理:采用从根集合(GC Roots)进行扫描,对存活的对象进行标记后,再将存活对象都向空闲的一端移动,并更新对应的指针,
          最后在清理掉端边界以外的内存 (先不清理,先移动再清理回收对象)
优点:
    不产生空间碎片:将所有存活对象整理到一端,边界以外被清理掉
缺点:
    效率低:标记-整理算法是在标记-清除算法的基础上,又进行了对象的移动,因此成本更高

复制算法(Copying):

代码语言:java
复制
复制算法:将可用内存分为大小相等两块,每次只使用其中一块,当该内存使用完后,就将该内存中活着的对象复制到另一块内存;然后再将已使用过得内存一次性清理
         这样每次都是对一块内存进行回收,且不存在内存碎片等情况,实现简单运行高效,但是代价是将内存缩小为原来的一半
优点:
    不产生空间碎片:一次清理一般内存空间
缺点:
    效率不稳定:复制算法的效率跟存活对象的数目多少有很大的关系,如果存活对象很多,那么复制算法的效率将会大大降低。  

https://segmentfault.com/a/1190000023379683

分代收集算法(Generational Collection) :

代码语言:java
复制
分代回收:核心思想是根据对象存活的生命周期将内存划分为若干个不同的区域,再根据不同的算法进行回收。
         一般情况下将堆区划分为老年代(Tenured Generation)和新生代(Young Generation),在堆区之外还有一个代就是永久代(Permanet Generation)
         新生代:每次垃圾回收时都有大量的对象需要被回收,对象存活率较低,可以采用"复制算法"。
         老年代:每次垃圾收集时只有少量的对象需要被回收,对象存活率较高,一般采用"标记清除、标记整理算法"。
         持久代:用于存放静态文件,如Java类,方法等,持久代也称为方法区。
分代回收分为两部分:        
    年轻代区域 (New Gen):Eden+Survivor(from/to)
                         Eden、Survivor(form)、Survivor(to),这 3 部分按照 8:1:1 的比例来划分新生代。
          新生成区 (Eden):存放的是新生成的对象,当 Eden 满了之后,年轻代 GC 就会启动,将生成空间的所有活动对象复制,不过目标区域是 Survivor 区
         幸存空间 (Survivor):Survivor区分为两个大小相等的空间(From/To),每次回收只会使用其中的一个。
                            1、当执行年轻代 GC 的时候,Eden 区的活动对象会被复制到 From 中;
                            2、当第二次年轻代 GC 时,会将 Eden 和 From 区内存活的对象一起复制到 To 区,之后再把 From/To 功能 "互换"
                               (这里的互换并没有互换数据,在程序中只是把引用换了)
    老年代区域 (Old Gen):
         1、对象中有一个 age 字段,代表对象经历的年轻代 GC 次数,新创建的对象年龄为 0,
         2、每经历一次年轻代 GC 还存活的对象年龄会加 1;
         3、在年轻代 GC 时,每次会检查对象的年龄,当超过一定限制(AGE_MAX)时,会将对象晋升到老年代。
回收流程         
    1、对象首先分配在伊甸园区域
    2、新生代空间不足时,触发 minor gc,伊甸园和 from 存活的对象使用复制算法复制到 Survivor(to) 中,存活的对象年龄加 1并且交换 Survivor(from/to)
       minor gc 会引发 stop the world,暂停其它用户的线程,等垃圾回收结束,用户线程才恢复运行。
    3、当对象寿命超过阈值时,会晋升至老年代,最大寿命是15(4bit)
    4、当老年代空间不足,会先尝试触发 minor gc,如果之后空间仍不足,那么触发 full gc,STW(stop the world) 的时间更长
分代回收相关 VM 参数:
    堆初始大小 			-Xms
    堆最大大小 			-Xmx 或 -XX:MaxHeapSize=size
    新生代大小 			-Xmn 或 (-XX:NewSize=size + -XX:MaxNewSize=size )
    幸存区比例(动态) 	-XX:InitialSurvivorRatio=ratio 和 -XX:+UseAdaptiveSizePolicy
    幸存区比例			-XX:SurvivorRatio=ratio
    晋升阈值 			-XX:MaxTenuringThreshold=threshold
    晋升详情 			-XX:+PrintTenuringDistribution
    GC详情 				-XX:+PrintGCDetails -verbose:gc
    FullGC 前 MinorGC 	-XX:+Scaveng

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档