¡Explicación detallada de la recolección de basura en la JVM! Análisis detallado de varios algoritmos de recolección de basura

¡Acostúmbrate a escribir juntos! Este es el quinto día de mi participación en el "Nuggets Daily New Plan·Desafío de actualización de abril", haz clic para ver los detalles del evento

Basura en la JVM

  • Definición: el objeto creado con la ejecución del método en la memoria de la JVM ya no se referencia ni se borra una vez que se completa la ejecución del método, y aún se almacena en la memoria. Este objeto al que no se volverá a hacer referencia es la basura en la JVM .
    • La mayoría de los objetos en la memoria de JVM se crean con la ejecución del método y no se volverá a hacer referencia a estos objetos después de ejecutar el método. Sin embargo, estos objetos no se borrarán, lo que generará más y más objetos en la memoria de JVM .
    • En este punto, se necesita un mecanismo para borrar estos objetos a los que no se volverá a hacer referencia.Estos objetos a los que no se volverá a hacer referencia son basura.

Definición de basura en la JVM

  • La JVM utiliza un mecanismo para borrar los objetos que no se volverán a utilizar. Antes de borrar los objetos basura, es necesario determinar qué objetos son basura reciclable y necesitan ser limpiados por la recolección de basura.

conteo de referencia

Análisis de principios

  • El conteo de referencias consiste en agregar un contador de referencias a cada objeto creado, utilizando un área de memoria adicional para almacenar la cantidad de veces que se hace referencia a cada objeto
  • Cada vez que se hace referencia a un objeto, el recuento de referencias del objeto se incrementa en 1. Cuando se invalida una referencia a un objeto, el recuento de referencias del objeto se reduce en 1
  • Cuando el recuento de referencias del objeto es 0 , se puede considerar que no se volverá a hacer referencia al objeto y que se puede recolectar basura.

ventaja

  • Intuitivo y eficiente
  • El método de conteo de referencia puede ubicar rápida e intuitivamente los objetos de basura que necesitan ser reciclados, para limpiar

pregunta

  • No se pueden resolver las referencias circulares:
    • Los objetos reciclables en el caso especial de las referencias circulares no se pueden escanear mediante el conteo de referencias.
    • Por ejemplo, dos objetos están referenciados de manera circular, pero no están referenciados por ningún otro objeto. En este momento, estos objetos también son objetos reciclables.
    • 此时,这种对象无法通过引用计数法进行定位进行垃圾回收
    • 垃圾无法回收,就会导致内存泄漏OOM问题
  • 维护成本比较大:
    • 引用计数法需要额外的内存空间记录每个对象被引用的次数
    • 并且这个引用数也要进行额外的维护

可达性分析法

  • 现在的主流程序设计语言都是通过可达性分析法来判断哪些对象是垃圾回收对象来进行垃圾回收的

原理分析

  • 可达性分析法以所有的GC Roots对象为出发点
    • 如果无法通过GC Roots的引用追踪到的对象,就认为这些对象不会被再次引用了
    • 此时,这些对象就可以进行垃圾回收了

inserte la descripción de la imagen aquí

  • 红色的是存活对象,不可以进行垃圾回收来清除的对象
  • 白色的是可以进行垃圾回收来清除的对象

GC Roots对象

  • GC Roots对象的条件:
    • GC Roots对象一定要在很长一段时间内都不会被GC回收,只有满足这个条件才能作为GC Roots对象
    • 普通的对象不能作为GC Roots对象
  • GC Roots对象的类型:
    • 虚拟机栈中的本地变量所引用的对象
    • 方法区中静态属性引用的对象
    • 方法区中常量引用的对象
    • 本地方法Native方法中引用的对象
    • 虚拟机内部引用的对象. 比如类记载器,基本数据对应的Class对象和异常对象
    • 同步锁Synchronnized持有的所有对象
    • 虚拟机内部情况描述的对象. 比如JXBean,JVMTI中注册的回调,本地缓存代码
    • 垃圾收集器所引用的对象

JVM中的垃圾回收

  • JVM中判断出哪些对象是可回收垃圾对象之后,就要进行垃圾对象的回收清除

标记清除算法

原理分析

  • 标记清除算法: 首先找到内存中的存活对象并对这些对象进行标记,然后统一将未标记的对象进行回收清除
  • 标记清除算法包含两个阶段:
    • 标记阶段: 对存活对象进行标记,确定出所有存活的对象
    • 清除阶段: 将未标记的对象清除

inserte la descripción de la imagen aquí

优点

  • 标记清除算法简单直接,速度非常快
  • 标记清除算法特别适合可回收对象不多的场景

问题

  • 容易造成不连续的内存空间,产生大量碎片,导致频繁的垃圾回收:
    • 清除后的内存中会有很多不连续的空间,也就是造成大量的空间碎片
    • 大量的空间碎片不但不利于下一次的分配,而且创建大对象时,尽管有足够容纳的空间,但是由于空间不连续造成对象无法进行分配,提前进行GC垃圾回收,导致频繁的垃圾回收
  • 性能不稳定:
    • 当内存中需要回收的对象较多,大量的对象都需要进行垃圾回收时,通常情况下,这些垃圾对象可能比较分散,造成清除过程非常耗时,导致垃圾回收清除的效率很低

标记复制算法

  • 标记清除算法最大的问题是会造成空间碎片并且只适合需要回收的对象比较少的场景. 针对这两个问题,就有了标记复制算法,标记复制算法专门针对这两个问题进行了解决
    • 标记清除算法的关注点是可回收的对象
    • 标记复制算法的关注点是存活的对象
  • 标记复制算法通过将存活的对象放到一个固定的区域,然后对其余区域的对象进行统一的清理

原理分析

  • 标记复制算法:
    • 标记复制算法中首件将年轻代内存划分出三块区域:
      • Eden区: 用于存放新创建的对象
      • S1区和S2区: 这两块用于存放存活的对象
    • 标记复制算法回收时的两种情况:
      • 一种是将Eden区和S1区存活的对象复制到S2区
      • 一种是将Eden区和S2区存活的对象复制到S1区

标记复制算法的回收时的两种情况说明S1区和S2区两块区域同时只会有一块区域使用,通过这种方式保证始终会有一块空白的区域用于下次垃圾回收GC时存放存活的对象,所以可以直接一次性清除所有的对象

  • 标记复制算法这样既简单直接同时也保证了清除后内存区域的连续性

inserte la descripción de la imagen aquí

优点

  • 标记复制算法解决了标记清除算法的空间碎片问题
  • 标记复制算法清除可回收对象的效率比较高. 标记清除算法采用移动存活对象的方式,每次清除都是针对一整块内存统一清除
    • 标记复制算法因为移动存活对象时会耗费一定的时间.总体来说,标记复制算法的效率会低于标记清除算法

问题

  • 造成内存的浪费:
    • 标记复制算法需要额外的内存作为复制区,总是会有一块空闲的内存区域无法利用. 造成内存资源的浪费
  • 存活对象较多时效率低:
    • 标记复制算法中复制移动对象的过程非常耗时. 不仅需要移动对象本身,还需要修改引用了这些对象的引用地址
    • 当存活对象越多时,标记复制算法复制移动对象的耗时越明显
    • 因此,标记清除算法适合存活对象比较少的场景
  • 需要担保机制:
    • 由于复制区总会有一块内存空间的浪费.为了控制内存空间的浪费,会将复制区的内存空间分配控制在很小的区间
    • 内存空间分配控制在很小的区间时会导致在存活对象较多时,分配的复制区的内存空间不能够容纳足够的存活对象
    • 这时,需要从其余的地方借用一些空间来保证容纳这些存活对象.这种从其余的地方借用内存的方式就是担保机制

担保机制

  • 一般情况下,标记复制算法将划分出的内存空间按照容量分为大小相等的两块空间. 两块内存空间交替使用,当一块内存空间使用完后,就先将存活的对象逐一复制到另一块未使用的内存空间中,然后将当前使用的这块内存空间一次性回收清除掉. 在出现当前内存空间中全部对象都是存活对象的极端情况时,因为两块内存空间大小相等,所以依旧满足条件
  • 担保机制: 分配担保
    • 为了提高内存利用率,提出来标记复制算法的改进方案:
      • 将内存空间按照一定的比例,比如 8 : 1 : 1 8:1:1 的比例分成3块
      • 较大的一块为Eden,较小的两块为Survivor.两块Survivor交替配合Eden一起使用
      • 垃圾回收时,先将存活对象复制到保留的Survivor中,然后将Eden和原来使用的Survivor一起回收清除掉
      • 由于Survivor的内存空间极小,极端情况下不能够容纳足够的存活对象,为了解决这个问题,就需要使用担保机制,使用一块额外的内存空间进行分配担保来将无法容纳的存活对象存放到额外的内存空间中

标记整理算法

  • 标记清除算法存在空间碎片的问题
  • 标记复制算法解决了空间碎片的问题,但是标记复制算法不适用于存活对象较多的情况
  • 在这样的具体场景和问题下,针对对于存活对象较多的情况进行垃圾回收清除并避免产生空间碎片,就有了标记整理算法

原理分析

  • 标记整理算法: 分为两个阶段
    • 标记阶段: 将存活对象和可回收对象标记出来
    • 整理阶段: 根据标记将存活对象向内存的一端移动,移动完存活对象后再回收清除可回收对象

inserte la descripción de la imagen aquí

优点

  • 标记整理法解决了标记清除法的空间碎片的问题
  • 标记整理法不需要空闲的内存空间,解决了标记复制法的内存浪费的问题
  • 标记整理法非常适合存活对象较多的场景

问题

  • 标记整理算法的性能较低:
    • 标记整理算法的复杂度大,执行步骤多
    • 标记整理算法在移动对象时不仅需要移动对象,还需要额外维护对象的引用的地址,这个过程需要对内存经过几次的扫描定位才能够完成

分代收集算法

  • 分代收集算法是目前大部分JVM的垃圾收集器使用的算法
  • 分代收集算法几种垃圾回收算法的集合体,指的是对不同的代使用不同的垃圾回收算法进行垃圾回收清除

原理分析

  • 分代收集算法:
    • 根据对象存活的生命周期将内存划分为若干个不同的区域. 对不同的代使用不同的算法实现
    • 一般将堆区分为新生代Young Generation, 老年代Tenured Generation和永久代Permanent Generation
      • 新生代Young Generation: Eden
        • 存放新创建的对象,对象生命周期非常短,几乎是使用完就立即回收
        • 使用标记复制算法进行垃圾回收
      • 老年代Tenured Generation: Old
        • 新生代区多次回收后存活下来的对象就会被移到老年代区
        • 由于对象存活率高,几乎没有额外的空间进行分配担保,使用标记清除算法或者标记整理算法
      • 永久代Permanent Generation: Java 8以后移除. 主要存放加载的类的信息,生命周期长,几乎不会被回收

垃圾回收总结

  • 这几种垃圾回收算法都有各自的特点,没有任何一种算法是完美的.需要根据具体的使用场景选择合适的垃圾回收算法

标记清除算法

  • Características: Velocidad de recolección rápida, simple y directa. Sin embargo, se producirá fragmentación del espacio, lo que resultará en operaciones frecuentes de recolección de basura y GC .
  • Escenas a utilizar:
    • Hay muchos objetos sobrevivientes. Solo una pequeña cantidad de objetos de basura necesitan ser reciclados.
    • Recolección de basura en la generación anterior. Suele haber más objetos vivos que objetos reciclables en la generación anterior.

Algoritmo de copia de marcas

  • Características: la recolección de elementos no utilizados es rápida y puede evitar la fragmentación del espacio. Sin embargo, provocará el desperdicio de espacio de memoria, lo que consume mucho tiempo en el caso de muchos objetos supervivientes y requiere un mecanismo de garantía.
  • Escenas a utilizar:
    • Menos objetos sobrevivientes
    • Recolección de basura de la nueva generación. Hay menos objetos sobrevivientes en la nueva generación. Por lo general, el recolector de basura de la nueva generación utilizará el algoritmo de copia de marca

Algoritmo de clasificación de marcas

  • Características: Comparado con el algoritmo de borrado de marcas, no causará fragmentación del espacio. Comparado con el algoritmo de copia de marcas, desperdicia espacio de memoria. Sin embargo, la eficiencia del algoritmo de clasificación de marcas es menor que la del algoritmo de borrado de marcas y la copia de marcas. algoritmo.
  • Escenas a utilizar:
    • Los recursos de memoria son escasos y es necesario evitar el problema de la fragmentación del espacio.
    • La generación anterior generalmente usa un algoritmo de clasificación de marcas para evitar el problema de fragmentación del espacio

Supongo que te gusta

Origin juejin.im/post/7086434645637595143
Recomendado
Clasificación