深入理解 JVM 垃圾接纳机制
在 Java 开发领域,JVM(Java 捏造机)的垃圾接纳机制是保障步伐高效稳固运行的关键环节。它自动处置惩罚内存管理中繁琐且易错的垃圾接纳任务。一、垃圾接纳的根本概念
在步伐运行过程中,会不绝创建各种对象,这些对象占用内存空间。当某些对象不再被步伐利用时,它们所占用的内存就需要被接纳,以便重新分配给其他新创建的对象。垃圾接纳机制就是 JVM 自动识别并接纳这些 “垃圾” 对象内存的过程。
那么,JVM 怎样判断一个对象是垃圾呢?这里重要有两种方法:
引用计数算法
每个对象都有一个引用计数器,当对象被引用时,计数器加 1;当引用失效时,计数器减 1。当计数器值为 0 时,表示该对象不再被引用,可以被接纳。然而,这种算法存在循环引用的问题,例如:
public class ReferenceCountingGC {
public Object instance = null;
public static void main(String[] args) {
ReferenceCountingGC objA = new ReferenceCountingGC();
ReferenceCountingGC objB = new ReferenceCountingGC();
objA.instance = objB;
objB.instance = objA;
// 此时,objA 和 objB 相互引用,但实际上它们已经没有外部引用,应该被回收,但引用计数算法无法处理这种情况
objA = null;
objB = null;
}
} 可达性分析算法
JVM 中的垃圾接纳器重要接纳可达性分析算法来确定对象是否为垃圾。该算法以一系列称为 “GC Roots” 的根对象作为起始点,从这些根对象开始向下搜索,搜索所走过的路径称为引用链。如果一个对象到 GC Roots 没有任何引用链相连,那么这个对象就是不可达的,可被判定为垃圾对象。GC Roots 通常包括以下几种对象:
[*]捏造机栈(栈帧中的本地变量表)中引用的对象。
[*]方法区中类静态属性引用的对象。
[*]方法区中常量引用的对象。
[*]本地方法栈中 JNI(即一样平常说的 Native 方法)引用的对象。
例如:
public class ReachabilityAnalysisGC {
public static void main(String[] args) {
Object obj1 = new Object();
Object obj2 = new Object();
// 将 obj2 赋值给 obj1 的成员变量,形成引用关系
obj1 = obj2;
// 此时,之前创建的第一个 Object 对象由于没有任何引用链可达 GC Roots,
将被判定为垃圾对象
}
} 二、常见的垃圾接纳算法
标记 - 扫除算法(Mark-Sweep)
这是最基础的垃圾接纳算法。它分为两个阶段:首先标记出所有需要接纳的对象,然后统一接纳被标记的对象。其优点是简单直接,缺点也很明显。标记和扫除过程服从不高,而且扫除后会产生大量不连续的内存碎片,当后续需要分配较大对象时,可能无法找到充足连续的内存空间,导致不得不提前触发另一次垃圾接纳。
复制算法(Copying)
将内存分别为大小相等的两块,每次只利用此中一块。当这一块内存用完后,就将存活的对象复制到另一块内存中,然后一次性清理掉利用过的那块内存。该算法的优点是简单高效,没有内存碎片问题,由于每次都是复制存活对象到新的连续内存空间。但它的代价是将可用内存缩小为原来的一半,对于内存资源紧张的环境不太友爱。在新生代中,由于大部分对象都是 “朝生夕死”,存活对象较少,所以比力适合利用复制算法,例如 Sun HotSpot 捏造机的新生代就接纳了这种算法,将新生代分别为 Eden 区和两个 Survivor 区(通常比例为 8:1:1)。
标记 - 整理算法(Mark-Compact)
结合了标记 - 扫除算法和复制算法的优点。首先标记出所有存活对象,然后将所有存活对象向一端移动,末了直接清理掉边界以外的内存。这样既解决了标记 - 扫除算法的内存碎片问题,又不需要像复制算法那样牺牲一半的内存空间。适用于老年代,由于老年代中的对象存活率较高,如果利用复制算法本钱太高。
分代收集算法(Generational Collection)
根据对象的存活周期将内存分别为差异的代,一样平常分为新生代和老年代。新生代中对象存活率低,接纳复制算法进行垃圾接纳;老年代中对象存活率高,接纳标记 - 整理算法或标记 - 扫除算法进行垃圾接纳。这种算法充分利用了差异代对象的特点,提高了垃圾接纳的服从。
三、JVM 中的垃圾接纳器
JVM 中有多种垃圾接纳器,它们各有特点,适用于差异的应用场景。
Serial 接纳器
这是一个单线程的垃圾接纳器,在进行垃圾接纳时会停息所有用户线程(“Stop The World”)。它的优点是简单高效,对于单 CPU 环境大概小型应用来说,由于没有线程切换的开销,性能体现不错。适用于客户端模式下的 JVM,例如一些简单的桌面应用步伐。
ParNew 接纳器
是 Serial 接纳器的多线程版本,在新生代接纳复制算法进行垃圾接纳。它能够充分利用多 CPU 的优势,提高垃圾接纳的服从。通常与 CMS 接纳器配合利用,在新生代利用 ParNew 接纳器,老年代利用 CMS 接纳器,适用于多 CPU 环境下的服务器应用。
Parallel Scavenge 接纳器
也是一个新生代垃圾接纳器,接纳复制算法。它的特点是关注系统的吞吐量,即单元时间内 CPU 用于运行用户代码的时间与 CPU 总消耗时间的比值。通过参数可以精确控制吞吐量的大小,适合在背景运算而不需要太多交互的任务,例如一些科学计算、数据处置惩罚等批处置惩罚任务。
Serial Old 接纳器
Serial 接纳器的老年代版本,是一个单线程的、接纳标记 - 整理算法的垃圾接纳器。重要用于在客户端模式下与 Serial 接纳器搭配利用,大概在服务端模式下作为 CMS 接纳器的后备预案,在并发收集发生 “Concurrent Mode Failure” 时利用。
Parallel Old 接纳器
Parallel Scavenge 接纳器的老年代版本,接纳标记 - 整理算法。在注重吞吐量的应用场景中,与 Parallel Scavenge 接纳器配合利用,能够在新生代和老年代都实现较高的吞吐量。
CMS 接纳器(Concurrent Mark Sweep)
以获取最短接纳停顿时间为目标的垃圾接纳器。它的工作过程比力复杂,重要分为四个阶段:初始标记、并发标记、重新标记和并发扫除。初始标记和重新标记阶段仍然需要停息所有用户线程,但时间很短;并发标记和并发扫除阶段与用户线程并发实验,大大淘汰了垃圾接纳时应用的停顿时间。适用于对相应时间要求较高的应用,如 Web 服务器等。但它也有一些缺点,例如会产生内存碎片,并且在并发阶段会占用肯定的 CPU 资源,影相应用的团体性能。
G1 接纳器(Garbage First)
面向服务端应用的垃圾接纳器,重要应用在多 CPU 和大内存的环境下。它将堆内存分别为多个大小相等的 Region,在进行垃圾接纳时,优先接纳垃圾最多的 Region。G1 接纳器接纳了标记 - 整理算法,避免了内存碎片问题,同时能够预测垃圾接纳的停顿时间,通过参数可以指定一个期望的停顿时间,让垃圾接纳在不影相应用相应时间的条件下进行。适用于大型的分布式系统、数据处置惩罚应用等对内存和相应时间都有较高要求的场景。
四、垃圾接纳的调优策略
在实际应用中,为了让 JVM 的垃圾接纳机制更好地顺应业务需求,往往需要进行一些调优。
确定垃圾接纳器
根据应用的范例、性能要求等因素选择符合的垃圾接纳器。例如,如果是对相应时间敏感的 Web 应用,可能优先考虑 CMS 接纳器或 G1 接纳器;如果是注重吞吐量的批处置惩罚应用,则可以选择 Parallel Scavenge 接纳器与 Parallel Old 接纳器的组合。
调整堆内存大小
公道设置新生代和老年代的大小。一样平常来说,可以根据应用中对象的生命周期特点进行调整。如果新生代设置过小,会导致频繁的 Minor GC;如果老年代设置过小,容易引发 Full GC。可以通过参数 -Xms(初始堆大小)和 -Xmx(最大堆大小)来设置堆内存的初始值和最大值,以及 -Xmn 来设置新生代的大小。
控制对象晋升到老年代的年龄
对象在新生代中经过多次 Minor GC 后仍然存活,就会晋升到老年代。可以通过参数 -XX:MaxTenuringThreshold 来调整对象晋升到老年代的年龄阈值,根据应用中对象的存活环境进行优化,避免过早或过晚地将对象晋升到老年代。
优化 CMS 接纳器
当利用 CMS 接纳器时,可以调整一些参数来优化其性能。例如,-XX:CMSInitiatingOccupancyFraction 参数可以设置老年代利用达到多少百分比时触发 CMS 接纳;-XX:+UseCMSCompactAtFullCollection 参数可以在 Full GC 后进行内存碎片整理,淘汰内存碎片的产生。
监控与分析
利用 JVM 提供的监控工具,如 jstat、jconsole、VisualVM 等,对垃圾接纳的过程进行监控和分析。通过检察垃圾接纳的频率、停顿时间、内存利用环境等指标,及时发现问题并进行调整。例如,如果发现 Full GC 过于频繁,可以进一步分析是内存泄漏导致对象无法接纳,照旧堆内存设置不公道等原因。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]