`

JVM GC算法

阅读更多

JVM GC算法

基础概念

 

GC Roots:

 The objects that a program can access directly are those objects which are referenced by local variables on the processor stack as well as by any static variables that refer to objects. In the context of garbage collection, these variables are called the roots

在Java语言中,包括但不限于以下几种:

1.虚拟机栈中引用的对象

2.方法区中类静态属性引用的对象

3.方法区中常量引用的对象

4.本地方法栈中JNI引用的对象

5.Thread对象

 

哪些对象该被GC?

如果一个对象到GC Roots没有任何引用链,该对象就是不可达对象,即可以被GC。

 

句柄(Handles):

The Java virtual machine specification does not prescribe how reference variables are implemented. A common approach is for a reference variable to be implemented as an index into an array of object handles . Every object instance has its own handle. The handle for an object typically contains a reference to a Class instance that describes the type of the object and a pointer to the region in the heap where the object data resides.

也就是说我们代码中的引用可能是直接引用对象,也可能是引用的是对象的句柄,对象的句柄再引用对象。用句柄的好处是当对象的地址改变时,只需改变句柄指向新的地址即可,即只需改一个地方,但是如果不用句柄的话就需要更新每一个引用。

 

 

一、标记清除算法(Mark-and-Sweep)

 When using mark-and-sweep, unreferenced objects are not reclaimed immediately. Instead, garbage is allowed to accumulate until all available memory has been exhausted. When that happens, the execution of the program is suspended temporarily while the mark-and-sweep algorithm collects all the garbage. Once all unreferenced objects have been reclaimed, the normal execution of the program can resume.

 

标记清除算法是最基础的收集算法,后面的算法都是基于该算法扩展的,分为两个阶段:

标记阶段(Mark phase):

从GC Roots出发,沿着引用链,遇到对象就标记该对象,直到所有可达对象都被标记。

清除阶段(Sweep phase):

扫描整个heap,回收那些在标记阶段未被标记的对象的内存。

 

标记(mark)伪码描述:

Java代码 
  1. for each root variable r  
  2.     mark (r);  
  3. sweep ();  

 

Cpp代码 
  1. void mark (Object p)  
  2.     if (!p.marked)  
  3.         p.marked = true;  
  4.         for each Object q referenced by p  
  5.             mark (q);  

 清除(sweep)伪码描述:

Cpp代码 
  1. void sweep ()  
  2.     for each Object p in the heap  
  3.         if (p.marked)  
  4.             p.marked = false  
  5.         else  
  6.             heap.release (p);  

 

图示描述(只有一个root,a为标记前,b为标记后清除前,c为清除后):

 

 

标记清除算法缺点:1.GC时用户线程必须暂停;2.标记和清除效率都不高;3.标记清除后会产生大量的内存碎片

 

 

二、停止复制算法(Stop-and-Copy)

When using the stop-and-copy garbage collection algorithm, the heap is divided into two separate regions. At any point in time, all dynamically allocated object instances reside in only one of the two regions--the active region. The other, inactive region is unoccupied.

 

停止复制算法将可用内存分为等量的两块,每次只使用其中的一块,当这一块无法满足新的内存分配时,即需要GC时,就扫描该块,将还存活的对象复制到另一块上面,然后再把已使用过的内存空间一次清理掉。

 

据研究,新生代的对象大多是短命的对象,所以不需要按照1:1的比例来划分内存空间,而是将内存划分为一块较大的Eden空间和两块较小的Survivor空间,每次使用Eden和其中一块Survivor。当回收时,将Eden和Survivor中还存活的对象一次复制到另外一块Survivor上,最后再清理Eden和原Survivor。Hotspot默认的比例Eden :Survivor = 8 :1.可以通过 -XX:SurvivorRatio=<N>来指定。值得注意的是,若复制时Survivor不够空间存放存活的Object了,则剩余的Object将进入Tenured Generation,即老年代。

 

Copy算法伪码描述(activeHeap:当前存放对象的那一块,inactiveHeap:当前未存放对象的那一块,forward引用所属对象在另一块中的复制对象,forward为null说明该对象还未被复制到另一块):

Cpp代码 
  1. for each root variable r  
  2.     r = copy (r, inactiveHeap);  
  3. swap (activeHeap, inactiveHeap);  

 

Cpp代码 
  1. void Object copy (Object p, Heap destination)  
  2.     if (p == null)  
  3.         return null;  
  4.     if (p.forward == null)  
  5.         q = destination.newInstance (p.class);  
  6.         p.forward = q;  
  7.         for each field f in p  
  8.             if (f is a primitive type)  
  9.                 q.f = p.f;  
  10.             else  
  11.                 q.f = copy (p.f, destination);  
  12.         q.forward = null;  
  13.     return p.forward;  

 

图示描述:

 

 

 

停止复制算法缺点:1.每次GC都要复制所有存活的对象,如果对象的存活率很高,那代价未免太大了;2.内存浪费,即使是按照Hotspot的Eden-Survivor来划分,仍有不少内存是浪费的。

 

 

三、标记整理(压缩)算法(Mark-and-Compact)

 

标记整理算法和标记清理算法类似,也分为两个阶段:

标记阶段(Mark):从GC Roots出发,沿着引用链,遇到对象就标记该对象,直到所有可达对象都被标记。

整理(压缩)阶段(Compact):把所有的存活对象往一端移,然后清理掉端边界外的内存。

 

图示句柄的用法:

 

 

可以看到所有对象都是和句柄关联而不是直接和引用(变量)关联。

 

标记过程伪码描述:

Cpp代码 
  1. void mark (Object p)  
  2.     if (!handle[p].marked)  
  3.         handle[p].marked = true;  
  4.         for each Object q referenced by p  
  5.             mark (q);  

 整理(压缩)算法伪码描述:

Cpp代码 
  1. void compact ()  
  2.     long offset = 0;  
  3.     for each Object p in the heap  
  4.         if (handle[p].marked)  
  5.             handle[p].object = heap.move (p, offset);  
  6.             handle[p].marked = false;  
  7.             offset += sizeof (p);  

 

 

 

 注意:无论是哪种算法哪种收集器,在枚举根节点时都是要停顿(停顿指得是暂停所有用户线程),只是根据算法的不同以及收集器的不同该停顿时间的长短不同而已。

0
1
分享到:
评论

相关推荐

    深入JVM内核—原理、诊断与优化视频教程-4.GC算法与种类

    在Java世界中,JVM(Java虚拟机)是运行所有Java应用程序的核心,它负责解析字节码、管理内存以及执行线程。...通过实践和研究GC算法及种类,开发者能更有效地管理内存,使Java应用程序运行更加高效。

    JVM调优,GC算法汇总

    了解并熟练掌握这些GC算法和JVM调优技巧,对于解决性能问题、优化Java应用的运行效率至关重要,同时也是面试中经常被问到的话题。通过实践和理解,开发者可以更好地理解和控制JVM的行为,从而编写出更高效、更稳定的...

    java基础学习JVM中GC的算法

    GC算法是JVM中的一种核心机制,它对Java程序的执行效率和内存使用情况产生了深远的影响。 在JVM中,GC算法可以分为两大类:Minor GC和Major GC。Minor GC是对年轻代(Young Generation)的垃圾回收,而Major GC是对...

    jvm gc

    Java虚拟机(JVM)的垃圾收集(Garbage Collection, GC)是Java程序运行时管理内存的关键机制。它自动地识别并释放不再使用的对象,从而避免了程序员手动管理内存可能导致的内存泄漏问题。理解JVM的GC对于优化Java...

    mac mat jvm gc 内存分析

    常见的GC算法有Serial、Parallel、CMS(Concurrent Mark Sweep)和G1(Garbage-First)等。 1. Serial GC:适用于单线程环境,采用复制算法,简单但可能导致应用暂停时间较长。 2. Parallel GC:多线程版本的Serial...

    jvm和gc详解及调优

    4. **垃圾收集机制**:GC是JVM自动管理内存的主要手段,涉及分代收集、标记-清除、复制、标记-整理等多种算法。书中会详细介绍各种算法的工作原理、优缺点,以及在不同场景下的选择。 5. **GC调优**:包括如何分析...

    JVM GC原理, heapsize调优

    选择正确的GC算法对于系统的性能至关重要。 4. 堆大小的调整(heapsize调优) 调整堆内存大小是性能调优的一个重要方面。堆内存大小调整涉及到年轻代和老年代的大小比例分配,以及整个堆的初始大小和最大大小设置。...

    用于测试jvm gc调优-share-jvm-gc.zip

    Java虚拟机(JVM)是Java程序运行的基础,它的垃圾收集器(GC)是自动管理内存的核心机制。在Java应用程序中,尤其是对于大型系统或高并发环境,进行JVM GC调优是提升性能、减少系统停顿时间的关键步骤。"用于测试...

    JVM体系结构与GC调优

    JVM体系结构与GC调优相关介绍,包含JVM体系结构、常用GC算法、内存管理、垃圾回收器、虚拟机调优、相关监控工具等

    jvm gc jvm调优 查看工具

    GC的工作机制包括新生代、老年代、永久代(在较新版本的JVM中已被元空间取代)等区域的划分,以及各种GC算法如复制算法、标记-清除算法、标记-整理算法和分代收集策略等。理解这些机制对于优化JVM性能至关重要。 ...

    IBM JVM GC 技术文档

    ### IBM JVM GC 技术文档知识点解析 #### 一、简介 IBM JVM(Java Virtual Machine)垃圾回收(Garbage Collection, GC)技术文档是针对IBM Developer Kit and Runtime Environment, Java 2 Technology Edition ...

    jvm 参数及gc详解

    Java虚拟机(JVM)是Java程序运行的基础,它的配置参数和垃圾收集(GC)机制对于优化应用程序性能至关重要。本文将深入探讨JVM参数及其与Java垃圾收集相关的知识。 一、JVM参数详解 JVM参数可以分为三类:启动参数...

    JVM_GC调优

    ### JVM_GC调优详解 #### 一、JVM体系结构概览 ...理解不同GC算法的特点和适用场景,可以帮助开发者选择最适合特定应用场景的垃圾回收策略。同时,掌握JVM内存模型和垃圾回收器的工作原理也是进行有效调优的基础。

    深入理解JVM&G1; GC

    《深入理解JVM & G1 GC》一书深入剖析了Java虚拟机(JVM)的工作原理,特别是针对垃圾收集器(GC)中的G1(Garbage-First)算法进行了详尽的探讨。JVM是Java程序运行的基础,它负责解析、编译、执行Java代码,并管理...

    高吞吐低延迟Java应用的垃圾回收优化.docx

    Oracle的Hotspot JVM内存管理白皮书是开始学习Hotspot JVM GC算法非常好的资料。 2.仔细考量GC需求:为降低应用性能的GC开销,可以优化GC的一些特征。吞吐量、延迟等这些GC特征应该长时间测试运行观察,确保特征...

    深入理解JVM & G1 GC

    JVM提供了多种GC算法,如串行GC、并行GC、并发Mark Sweep(CMS)和G1 GC等。 G1 GC是Oracle JVM从Java 6 Update 24引入的一种新一代垃圾收集器,它的设计目标是实现可预测的暂停时间模型,即在垃圾收集过程中,能...

    JVM、GC详解及调优_jvm_JVM、GC详解及调优_

    5. **内存分配策略**:如使用CMS或G1等高级GC算法,降低STW影响。 此外,JVM调优还包括JVM参数的调整,如堆大小(-Xms, -Xmx)、初始堆大小(-Xmn)、Metaspace大小(-XX:MaxMetaspaceSize)等。理解JIT编译器的...

    GC算法与种类

    java,GC,算法,可触及性,stop-the-world是一篇描述GC工作的文章

Global site tag (gtag.js) - Google Analytics