【JVM】垃圾回收算法

有哪些常见的垃圾回收算法?

1.1960年John McCarthy发布了第一个GC算法:标记-清除算法。

2.1963年Marvin L. Minsky 发布了复制算法。

3.标记--整理算法

4.分代GC算法

标记清除算法

什么是标记清除算法?

标记清除算法的核心思想分为两个阶段:
1.标记阶段,将所有存活的对象进行标记。Java中使用可达性分析算法,从GC Root开始通过引用链遍历出所有存活对象。
2.清除阶段,从内存中删除没有被标记也就是非存活对象

标记清除算法的优缺点

优点:实现简单,只需要在第一阶段给每个对象维护标志位,第二阶段删除对象即可。
缺点:1.碎片化问题由于内存是连续的,所以在对象被删除之后,内存中会出现很多细小的可用内存单元。如果我们需要的是一个比较大的空间,很有可能这些内存单元的大小过小无法进行分配。


2.分配速度慢。由于内存碎片的存在,需要维护一个空闲链表,极有可能发生每次需要遍历到链表的最后才能获得合适的内存空间。

复制算法

什么是复制算法

复制算法的核心思想是:
1.准备两块空间From空间和To空间,每次在对象分配阶段,只能使用其中一块空间(From空间)
2.在垃圾回收GC阶段,将From中存活对象复制到To空间。
3.将两块空间的From和To名字互换。

复制算法的优缺点

优点

吞吐量高 :复制算法只需要遍历一次存活对象复制到To空间即可,比标记-整理算法少了一次遍历的过程,因而性能较好,但是不如标记-清除算法,因为标记清除算法不需要进行对象的移动

不会发生碎片化:复制算法在复制之后就会将对象按顺序放入To空间中,所以对象以外的区域都是可用空间,不存在碎片化内存空间.

缺点

内存使用效率低:每次只能让一半的内存空间来为创建对象使用

标记整理算法

什么是标记清除算法

        标记整理算法也叫标记压缩算法,是对标记清理算法中容易产生内存碎片问题的一种解决方案。
核心思想分为两个阶段:
1.标记阶段,将所有存活的对象进行标记。Java中使用可达性分析算法,从GC Root开始通过引用链遍历出所有存活对象。
2.整理阶段,将存活对象移动到堆的一端。清理掉存活对象的内存空间。

标记整理算法的优缺点

优点

内存使用效率高:整个堆内存都可以使用,不会像复制算法只能使用半个堆内存

不会发生碎片化:在整理阶段可以将对象往内存的一侧进行移动,剩下的空间都是可以分配对象的有效空间

缺点

整理阶段的效率不高:整理算法有很多种,比如Lisp2整理算法需要对整个堆中的对象搜索3次,整体性能不佳。可以通过TwoFinger、表格算法、ImmixGC等高效的整理算法优化此阶段的性能

分代垃圾回收算法

什么是分代垃圾回收算法

        现代优秀的垃圾回收算法,会将上述描述的垃圾回收算法组合进行使用,其中应用最广的就是分代垃圾回收算法(Generational GC)。分代垃圾回收将整个内存区域划分为年轻代和老年代:

        分代回收时,创建出来的对象,首先会被放入Eden伊甸园区。
        随着对象在Eden区越来越多,如果Eden区满,新创建的对象已经无法放入,就会触发年轻代的GC,称为Minor GC或者Young GC。Minor GC会把需要eden中和From需要回收的对象回收,把没有回收的对象放入To区。

        接下来,S0会变成To区,S1变成From区。当eden区满时再往里放入对象,依然会发生Minor GC。此时会回收eden区和S1(from)中的对象,并把eden和from区中剩余的对象放入S0。
注意:每次Minor GC中都会为对象记录他的年龄,初始值为0,每次GC完加1。

        如果Minor GC后对象的年龄达到阈值(最大15,默认值和垃圾回收器有关),对象就会被晋升至老年代。
        当老年代中空间不足,无法放入新的对象时,先尝试minor gc如果还是不足,就会触发Full GC,Full GC会对整个堆进行垃圾回收。
        如果Full GC依然无法回收掉老年代的对象,那么当对象继续放入老年代时,就会抛出Out Of Memory异常。

分代垃圾回收算法优点

        程序中大部分对象都是朝生夕死,在年轻代创建并且回收,只有少量对象会长期存活进入老年代。分代垃圾回收的优点有:

1、可以通过调整年轻代和老年代的比例来适应不同类型的应用程序,提高内存的利用率和性能。

2、新生代和老年代使用不同的垃圾回收算法,新生代一般选择复制算法效率高、不会产生内存碎片,老年代可以选择标记-清除和标记-整理算法,由程序员来选择灵活度较高。

3、分代的设计中允许只回收新生代(minor gc),如果能满足对象分配的要求就不需要对整个堆进行回收(full gc),STW(Stop The World)由垃圾回收引起的停顿时间就会减少。

相关推荐

  1. JVM垃圾回收算法

    2024-03-20 06:14:03       32 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-20 06:14:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-20 06:14:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-20 06:14:03       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-20 06:14:03       20 阅读

热门阅读

  1. 无法加载DLL“SQLite.Interop.dll“:找不到指定模块

    2024-03-20 06:14:03       17 阅读
  2. ES-Hadoop:将Elasticsearch与Hadoop无缝集成的开源工具

    2024-03-20 06:14:03       19 阅读
  3. 【ML】逻辑回归、生成式与判别式引出 3

    2024-03-20 06:14:03       21 阅读
  4. C#面:什么是自定义异常

    2024-03-20 06:14:03       19 阅读
  5. [游戏开发][Unity] 导出Xcode工程,完成调试与发布

    2024-03-20 06:14:03       18 阅读
  6. Android 逆向(三)-adb常用逆向命令

    2024-03-20 06:14:03       18 阅读
  7. C++ 类模板

    2024-03-20 06:14:03       17 阅读
  8. YOLOv8-pose自定义关键点推理封装

    2024-03-20 06:14:03       18 阅读
  9. 安卓面试题多线程41-45

    2024-03-20 06:14:03       16 阅读