Java语言规范没有明确地说明JVM使用哪种垃圾回收算法,但是任何一种垃圾收集算法一般要做2件基本的事情:(1)发现无用信息对象;(2)回收被无用对象占用的内存空间,使该空间可被程序再次使用。
大多数垃圾回收算法使用了根集(root set)这个概念;所谓根集就量正在执行的Java程序可以访问的引用变量的集合(包括局部变量、参数、类变量),程序可以使用引用变量访问对象的属性和调用对象的方法。垃圾收集首选需要确定从根开始哪些是可达的和哪些是不可达的,从根集可达的对象都是活动对象,它们不能作为垃圾被回收,这也包括从根集间接可达的对象。而根集通过任意路径不可达的对象符合垃圾收集的条件,应该被回收。下面介绍几个常用的算法。
1、 引用计数法(Reference Counting Collector)
引用计数法是唯一没有使用根集的垃圾回收的法,该算法使用引用计数器来区分存活对象和不再使用的对象。一般来说,堆中的每个对象对应一个引用计数器。当每一次创建一个对象并赋给一个变量时,引用计数器置为1。当对象被赋给任意变量时,引用计数器每次加1当对象出了作用域后(该对象丢弃不再使用),引用计数器减1,一旦引用计数器为0,对象就满足了垃圾收集的条件。
基于引用计数器的垃圾收集器运行较快,不会长时间中断程序执行,适宜地必须 实时运行的程序。但引用计数器增加了程序执行的开销,因为每次对象赋给新的变量,计数器加1,而每次现有对象出了作用域生,计数器减1。
ps:用根集的方法(既有向图的方法)进行内存对象管理,可以消除循环引用的问题.就是说如果有三个对象相互引用,只要他们和根集是不可达的,gc也是可以回收他们.根集的方法精度很高,但是效率低.计数器法精度低(无法处理循环引用),但是执行效率高.
2、tracing算法(Tracing Collector)
tracing算法是为了解决引用计数法的问题而提出,它使用了根集的概念。基于tracing算法的垃圾收集器从根集开始扫描,识别出哪些对象可达,哪些对象不可达,并用某种方式标记可达对象,例如对每个可达对象设置一个或多个位。在扫描识别过程中,基于tracing算法的垃圾收集也称为标记和清除 (mark-and-sweep)垃圾收集器。
3、compacting算法(Compacting Collector)
为了解决堆碎片问题,基于tracing的垃圾回收吸收了Compacting算法的思想,在清除的过程中,算法将所有的对象移到堆的一端,堆的另一端就变成了一个相邻的空闲内存区,收集器会对它移动的所有对象的所有引用进行更新,使得这些引用在新的位置能识别原来 的对象。在基于Compacting 算法的收集器的实现中,一般增加句柄和句柄表。
4、copying算法(Coping Collector)
该算法的提出是为了克服句柄的开销和解决堆碎片的垃圾回收。
将内存分为两个区域(from space和to space)。所有的对象分配内存都分配到from space。在清理非活动对象阶段,把所有标志为活动的对象,copy到to space,之后清楚from space空间。然后互换from sapce和to space的身份。既原先的from space变成to sapce,原先的to space变成from space。每次清理,重复上述过程。
优点:copy算法不理会非活动对象,copy数量仅仅取决为活动对象的数量。并且在copy的同时,整理了heap空间,即,to space的空间使用始终是连续的,内存使用效率得到提高。
缺点:划分from space和to space,内存的使用率是1/2。收集器必须复制所有的活动对象,这增加了程序等待时间。
5、generation算法(Generational Collector)
来自IBM的一组统计数据:98%的java对象,在创建之后不久就变成了非活动对象;只有2%的对象,会在长时间一直处于活动状态。
(1)young generation
年轻代分三个区。一个Eden区,两个Survivor区。大部分对象在 Eden区中生成。当Eden区满时,还存活的对象将被复制到Survivor区(两个中的一个),当这个Survivor区满时,此区的存活对象将被复制到另外一个Survivor区,当这个Survivor区也满了的时候,从第一个Survivor区复制过来的并且此时还存活的对象,将被复制到 tenured generation。需要注意,Survivor的两个区是对称的,没先后关系,所以同一个区中可能同时存在从Eden复制过来对象,和从前一个 Survivor复制过来的对象,而复制到年老区的只有从第一个Survivor去过来的对象。而且,Survivor区总有一个是空的。
young generation的gc称为minor gc。经过数次minor gc,依旧存活的对象,将被移出young generation,移到tenured generation
(2)tenured generation
生命周期较长的对象,归入到tenured generation。一般是经过多次minor gc,还 依旧存活的对象,将移入到tenured generation。(当然,在minor gc中如果存活的对象的超过survivor的容量,放不下的对象会直接移入到tenured generation)
tenured generation的gc称为major gc,就是通常说的full gc。
采用compaction算法。由于tenured generaion区域比较大,而且通常对象生命周期都比较长,compaction需要一定时间。所以这部分的gc时间比较长。
minor gc可能引发full gc。当eden+from space的空间大于tenured generation区的剩余空间时,会引发full gc。这是悲观算法,要确保eden+from space的对象如果都存活,必须有足够的tenured generation空间存放这些对象。
(3)permanent generation
该区域比较稳定,主要用于存放classloader信息,比如类信息和method信息。
对于spring hibernate这些需要动态类型支持的框架,这个区域需要足够的空间。(这部分空间应该存在于方法区而不是heap中)。
6、adaptive算法(Adaptive Collector)
在特定的情况下,一些垃圾收集算法会优于其它算法。基于Adaptive算法的垃圾收集器就是监控当前堆的使用情况,并将选择适当算法的垃圾收集器。
相关推荐
java,GC,算法,可触及性,stop-the-world是一篇描述GC工作的文章
#### 二、GC算法原理 GC算法的核心思想是将立体匹配问题转化为图割问题来求解。具体而言,对于每一对可能对应的像素点,算法都会基于代价函数计算它们匹配的可能性,并构建一个能量函数模型来衡量整个匹配结果的...
在Java世界中,JVM(Java虚拟机)是运行所有Java应用程序的核心,它负责解析字节码、管理内存以及执行线程。...通过实践和研究GC算法及种类,开发者能更有效地管理内存,使Java应用程序运行更加高效。
本文将深入探讨GC算法在C++中的实现,以及如何生成视差图。 首先,GC算法基于能量最小化理论,其目标是找到一个视差分配方案,使得整个系统的能量达到最小。能量函数通常由两部分组成:数据项和平滑项。数据项衡量...
GC算法是C++等编程语言中实现内存管理的重要部分,尽管C++标准库并不直接提供垃圾收集机制,但许多现代C++库和框架如智能指针、内存池等都在一定程度上实现了类似的功能。在这个GC算法笔记中,我们将深入探讨GC的...
f2fs——FG_GC优化之从GREEDY算法修改为CAT算法源码
在JVM中,有多种不同的GC算法,每种都有其特定的应用场景和优缺点。 1. **串行GC(Serial GC)**:这是最基础的GC算法,适合于单CPU环境。它在一个线程中执行GC操作,因此在GC过程中会暂停应用执行(Stop-The-World...
本文将详细探讨GC算法、判断对象回收条件、垃圾收集器的工作原理及其调优步骤和常用参数。 首先,GC需要判断哪些对象可以被回收。在JVM中,主要有两种算法用来判断对象的生死:引用计数法和可达性分析算法。引用...
GC算法是JVM中的一种核心机制,它对Java程序的执行效率和内存使用情况产生了深远的影响。 在JVM中,GC算法可以分为两大类:Minor GC和Major GC。Minor GC是对年轻代(Young Generation)的垃圾回收,而Major GC是对...
GC算法的选择和优化是系统性能的关键因素之一。不同的算法有不同的优缺点,适应不同的场景。现代的垃圾回收器往往结合多种算法,以达到高效、低延迟的目标。例如,Java的HotSpot虚拟机就使用了分代收集、压缩复制等...
RGW 的 GC 深入解析与调优 GC(Garbage Collection,垃圾回收)是RGW 中的一种异步磁盘空间回收操作。GC 的出现是为了释放无用的对象占用的磁盘空间,提高存储设备的利用率。在 RGW 中,GC 通常发生在以下三种情况...
Python脚本可能用于计算不同位置的读取深度(depth)和GC内容之间的关系,或者实现某种GC校正算法。R脚本则可能提供了数据分析和可视化功能,R语言在生物信息学中广泛用于数据处理和统计分析。 在实际操作中,GC...
在讨论气相色谱法(GC)测试双酚A(BPA)含量的知识点之前,我们首先需要理解BPA是什么,它的重要性,以及为什么需要通过GC技术来测试它的含量。双酚A(Bisphenol A)是一种常见的工业化学品,广泛用于生产塑料和...
《MT65xx_GC032A_Driver_20170614_GC032A_GC032A_Drive》是一款专为MT65xx平台设计的GC032A图像传感器驱动程序,它在原有的厂家驱动基础上进行了一些定制化的改进,以优化性能和效果。此驱动程序的更新日期为2017年6...
gc-viz, 几种垃圾收集算法的动画可视化 gc几种垃圾收集算法的动画可视化。makeopen MARK_SWEEP_GC.gifGIF输出需要安装 ImageMagick 。 编辑生成文件以选择不同的算法。 如果向该示例添加更多数据,则可能必须增加G
GC总结
总的来说,理解JVM的类加载机制、内存结构、GC算法和调优是成为一名熟练的Java开发者的必备知识。这不仅能帮助开发者编写更高效的代码,还能有效地避免内存泄漏和性能瓶颈,提升应用程序的稳定性和性能。