JVM之垃圾回收算法详解

简介: JVM之垃圾回收算法详解

JVM之垃圾回收算法详解

现有的垃圾回收算法

分类

根据如何判定对象是垃圾,垃圾回收算法分为两类:

1、引用计数式垃圾收集(判定垃圾是通过引用计数器)别名:直接垃圾收集

2、追踪式垃圾收集(判定垃圾是通过GC Roots)别名:间接垃圾收集

主流虚拟机采用的是第二种追踪式垃圾收集,所以本文讲解第二种垃圾收集的算法

垃圾收集器的设计原则

根据两个分代假说:

1.绝大部分对象是熬不过第一次垃圾回收的

2.熬过多次垃圾回收的对象是难以被标记为垃圾的。

垃圾收集器将堆中的内存划分为了不同的区域,根据对象分代年龄(熬过多少次垃圾回收)来分配到不同的区域中:

比如对象分代年龄小的,第一种对象就应该标记存活对象即可,而不需要标记那些垃圾对象,因为这部分对象大部分都是很快用完就不用的垃圾对象。

而第二种对象分代年龄大的,则应该标记的是垃圾对象,因为根据第二个假说这部分对象中垃圾对象的占比很少,所以垃圾回收的频率也可以降低。

将堆划分为不同的区域后,垃圾回收器可以只回收其中一部分区域,针对每一部分区域也可以采用不同的算法来进行回收垃圾。

一般来说堆中至少会被划分为“新生代”和“老年代”两个区域。新生代存储第一种假说类型的对象,老年代存放第二种假说类型的对象。

注意:这种设计看起来是完美的,但是如果老年代中的对象引用了新生代中的对象这个时候年轻代发生垃圾回收时,除了需要遍历GC Roots外,还需要遍历整个老年代才会确保年轻代中的对象真正没有对象引用。显然这种遍历整个老年代效率肯定会很低,所以采用了一种解决方案:读者有兴趣可以看看: 在这篇博客的末尾

标记-清除算法

最早出现的垃圾回收算法,之后出现的算法都是根据其缺点来进行演进的。

两个阶段:

1.标记

2.清除

标记需要回收的对象完成后进行统一回收所有被标记的对象,
也可以标记存活的对象统一回收没有被标记的对象。

一,标记

如何判定对象是否是垃圾的过程在上一篇 博客 中已经讲解过,接着标记这些垃圾对象。

二,清除

进行统一回收掉标记的对象。

缺点

1.当堆中的对象大部分是垃圾时,标记和清除的效率会变低,而且会随着内存中垃圾对象的增长,导致效率越来越低。

2.内存碎片化:因为内存分配不是连续的,所以当清除后,内存中会存在大量内存碎片。当遇到大对象分配内存找不到足够的连续的内存来存放时会提前触发GC。

标记-复制算法

采用的是“半区复制”的算法来实现的,即每次只使用其中的一部分内存,当这部分内存用完后将存活着的对象复制到另外一块内存上,接着清空刚才使用的那部分内存,当另一部分内存满了的时候再用上一次清空后的那块内存往复。

解决了标记-清除的内存碎片化问题,因为当发生GC时会进行全部清空,只将存活对象复制到另外一块内存中。

“Apple回收策略”

Andrew Appel针对刚刚分代假说中的第一条,提出了“Appel式回收策略”。

一般情况下百分之九十八的对象在经历第一次gc时就会被清除。因此做出优化将年轻代分为了一块eden空间和两块Survival空间。enen和Survival内存占比为8:1,即每次使用百分之九十的内存,只有百分之十的内存会被浪费,因为对象大部分都会死去所以没有必要分配一半的空间来存放存活对象。

但是如果使用百分之十的内存来存放存活对象,当存活对象在Survival空间存放不下时,这个时候就需要用老年代担保,因此当存不下时会存放到老年代中。

缺点

1.当内存中的对象存活率较高时,复制大量存活对象会使得效率变低。

2.如果不想造成严重的内存浪费,就需要有额外的空间进行分配。

标记-整理算法

上面所说的标记-复制算法针对与新生代中进行的回收算法,并不适用与老年代,原因:老年代中存活率较高,存放不下时需要额外的内存空间担保。

因此出现了标记-整理算法,

和标记-复制算法相同的是:标记的都是存活对象

和标记-复制算法不同的是:复制算法将存活对象复制到另外一块内存上然后清除之前使用的内存,而整理算法是移动存活的对象到一端,然后清除边界以外的内存

缺点

移动存活对象

对于老年代中GC之后大部分都为存活对象,将这些对象都进行移动并且更新引用这些对象的地方是一个比较耗时的操作。而且更新引用需要暂停用户线程来保证用户线程访问对象不会出错,简称STW,“Stop the Word”。

其实不止整理算法里面移动对象更新引用需要STW,清除算法和复制算法中的标记清除都需要STW,只不过时间短

总结

采用标记-整理算法意味着GC的时候要移动对象更新对象的引用,也就是说内存回收的时候会更复杂

采用标记-清除算法意味着内存碎片化

采用标记-复制算法意味着内存可用度不高

“吞吐量”:赋值器(使用垃圾回收器的线程也就是用户线程)与垃圾回收器的效率总和。

因为内存分配和访问(内存碎片化导致过多的分配和访问)比垃圾回收器回收的频率(回收时需要STW,而且比较耗时)要高,因此整理这种方式其实吞吐量要比清除要好。

对于关注吞吐量的收集器Parallel Scabenge基于标记-整理算法,

对于关注STW的收集器CMS来说采用的是标记-清除算法。

其实CMS是一种将两种算法混合起来的收集器,大部分时间采用清除算法,只有当分配内存不足(碎片化特别严重)时用整理算法进行一次收集。


相关文章
|
4月前
|
Arthas 存储 算法
深入理解JVM,包含字节码文件,内存结构,垃圾回收,类的声明周期,类加载器
JVM全称是Java Virtual Machine-Java虚拟机JVM作用:本质上是一个运行在计算机上的程序,职责是运行Java字节码文件,编译为机器码交由计算机运行类的生命周期概述:类的生命周期描述了一个类加载,使用,卸载的整个过类的生命周期阶段:类的声明周期主要分为五个阶段:加载->连接->初始化->使用->卸载,其中连接中分为三个小阶段验证->准备->解析类加载器的定义:JVM提供类加载器给Java程序去获取类和接口字节码数据类加载器的作用:类加载器接受字节码文件。
412 55
|
9月前
|
监控 算法 Java
Java虚拟机(JVM)垃圾回收机制深度剖析与优化策略####
本文作为一篇技术性文章,深入探讨了Java虚拟机(JVM)中垃圾回收的工作原理,详细分析了标记-清除、复制算法、标记-压缩及分代收集等主流垃圾回收算法的特点和适用场景。通过实际案例,展示了不同GC(Garbage Collector)算法在应用中的表现差异,并针对大型应用提出了一系列优化策略,包括选择合适的GC算法、调整堆内存大小、并行与并发GC调优等,旨在帮助开发者更好地理解和优化Java应用的性能。 ####
224 27
|
10月前
|
监控 算法 Java
Java虚拟机(JVM)的垃圾回收机制深度解析####
本文深入探讨了Java虚拟机(JVM)的垃圾回收机制,旨在揭示其背后的工作原理与优化策略。我们将从垃圾回收的基本概念入手,逐步剖析标记-清除、复制算法、标记-整理等主流垃圾回收算法的原理与实现细节。通过对比不同算法的优缺点及适用场景,为开发者提供优化Java应用性能与内存管理的实践指南。 ####
|
4月前
|
缓存 算法 Java
JVM深入原理(八)(一):垃圾回收
弱引用-作用:JVM中使用WeakReference对象来实现软引用,一般在ThreadLocal中,当进行垃圾回收时,被弱引用对象引用的对象就直接被回收.软引用-作用:JVM中使用SoftReference对象来实现软引用,一般在缓存中使用,当程序内存不足时,被引用的对象就会被回收.强引用-作用:可达性算法描述的根对象引用普通对象的引用,指的就是强引用,只要有这层关系存在,被引用的对象就会不被垃圾回收。引用计数法-缺点:如果两个对象循环引用,而又没有其他的对象来引用它们,这样就造成垃圾堆积。
133 0
|
4月前
|
算法 Java 对象存储
JVM深入原理(八)(二):垃圾回收
Java垃圾回收过程会通过单独的GC线程来完成,但是不管使用哪一种GC算法,都会有部分阶段需要停止所有的用户线程。这个过程被称之为StopTheWorld简称STW,如果STW时间过长则会影响用户的使用。一般来说,堆内存越大,最大STW就越长,想减少最大STW,就会减少吞吐量,不同的GC算法适用于不同的场景。分代回收算法将整个堆中的区域划分为新生代和老年代。--超过新生代大小的大对象会直接晋升到老年代。
95 0
|
6月前
|
缓存 监控 算法
JVM简介—2.垃圾回收器和内存分配策略
本文介绍了Java垃圾回收机制的多个方面,包括垃圾回收概述、对象存活判断、引用类型介绍、垃圾收集算法、垃圾收集器设计、具体垃圾回收器详情、Stop The World现象、内存分配与回收策略、新生代配置演示、内存泄漏和溢出问题以及JDK提供的相关工具。
JVM简介—2.垃圾回收器和内存分配策略
|
6月前
|
监控 算法 Java
JVM—垃圾收集算法和HotSpot算法实现细节
JVM的垃圾收集算法和HotSpot的实现细节复杂但至关重要,通过理解和掌握这些算法,可以为Java应用程序选择合适的垃圾收集器,并进行有效的性能调优。选择适当的垃圾收集策略,结合合理的内存配置和日志分析,能够显著提升应用的运行效率和稳定性。
101 15
|
10月前
|
机器学习/深度学习 监控 算法
Java虚拟机(JVM)的垃圾回收机制深度剖析####
本文深入探讨Java虚拟机(JVM)的垃圾回收机制,揭示其工作原理、常见算法、性能调优策略及未来趋势。通过实例解析,为开发者提供优化Java应用性能的思路与方法。 ####
221 28
|
9月前
|
算法 网络协议 Java
【JVM】——GC垃圾回收机制(图解通俗易懂)
GC垃圾回收,标识出垃圾(计数机制、可达性分析)内存释放机制(标记清除、复制算法、标记整理、分代回收)
|
9月前
|
存储 监控 算法
Java虚拟机(JVM)垃圾回收机制深度解析与优化策略####
本文旨在深入探讨Java虚拟机(JVM)的垃圾回收机制,揭示其工作原理、常见算法及参数调优方法。通过剖析垃圾回收的生命周期、内存区域划分以及GC日志分析,为开发者提供一套实用的JVM垃圾回收优化指南,助力提升Java应用的性能与稳定性。 ####

热门文章

最新文章