zoukankan      html  css  js  c++  java
  • JVM学习笔记——GC概述

    title: JVM学习笔记——GC概述
    date: 2018/9/2 12:05:00
    description: 最近开始着手JVM的学习,在这里把自己学习过程中的笔记分享出来,希望能帮到一些小伙伴,同时也是对自己的学习的一个梳理。

    GC概述

    其实GC主要就是思考以下三件事情:

    • 哪些内存需要回收?
    • 什么时候回收?
    • 如何回收?

    • 哪些内存需要回收

      主要针对Java堆和方法区,程序计数器、虚拟机栈、本地方法栈内存分配与回收具有确定性,所以不需要过多考虑GC的问题。
      其中方法区的回收主要针对以下两种:

      • 回收常量
        没有任何地方引用到该常量时,该常量将会被回收。
      • 回收无用类
        同时满足以下几个条件则视为“无用类”。
        • Java堆中不存在任何该类的实例
        • 加载该类的ClassLoader已经被回收
        • 该类的java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问到该类。
    • 什么时候回收(判断对象是否“死去”)

      • 引用计数算法

        为对象增加一个引用计数器,每有一次引用则计数器+1,失去一个引用则计数器-1。这种算法效率很高,实现也很简单,但是在相互引用的情况下,会出现无法回收的情况。例如:a.instance = b; b.instance = a;

      • 可达性分析算法

        使用GC Roots作为起始点,当一个对象到GC Roots没有引用链路时(即不可达),则此时对象视为“死亡”。此方法也是现有JVM中常用的算法。
        GC Roots包括下面几种:

        • 虚拟机栈(栈帧中的本地变量表)中引用的对象
        • 本地方法栈中Native方法引用的对象
        • 方法区中类静态属性引用的对象
        • 方法区中常量引用的对象

        换句话来说,以上4中类型其实就是:类成员变量,类静态变量,常量,局部变量,只要某个对象不被以上4种类型关联到,那么该对象就是“已死”的,gc时就会被回收内存空间。

    • 如何回收(垃圾收集算法)

      • 标记-清除算法(Mark-Sweep)

        Mark-Sweep
        它是最基础的算法,后续的算法都是针对它的缺点改进而生。它存在两个缺点:

        • 效率问题。标记与清除这两个过程效率都不高。
        • 空间问题。如图所示,清除后的内存空间是不规整的,会产生大量的内存碎片。大量的碎片会导致分配大对象时,找不到连续的内存空间而提前触发另一次GC。

      • 复制算法(Copying)

        Copying
        针对标记-清除的效率问题,复制算法将内存分为两块空间,每次只使用其中一块。当这块的内存空间用完时,将存活的对象移到另一块中,然后将已使用的内存空间一次性清理掉。这样做的好处是不会产生碎片,清除也是针对连续的空间做处理,只要移动堆指针就行。
        实际上在现在的虚拟机中,将这种算法应用在新生代。按照8:1:1的比例将内存分为三块,每次使用一块较大的与较小的其中一块,清理时将存活对象移到剩下的一块中,这样每次只会浪费10%的内存,由于新生代中的内存一般都是“朝生夕死”的,使用这种算法可以极大的提升效率。但是,不能保证每次清理时,剩下的一块空间能够存放所有的存活对象,所以这里会依赖其他内存空间(一般指老年代)进行分配担保(Handle Promotion)。

      • 标记-整理算法(Mark-Compact)

        Mark-Compact
        复制算法在对象存活率较高时,效率就会变低,所以针对高对象存活率的情况,就有人提出了该算法。标记的过程并没有变化,但标记后并不是进行“清除”,而是将存活的对象向一端进行移动整理,然后清除掉其余的空间。现代虚拟机常将这种算法在老年代中使用。

      • 分代收集算法(Generational Collection)

        分代收集算法是根据对象的存活时间,将内存划分几块(一般分为新生代和老年代),这样就可以根据不同的内存区域特点采用不同的算法。针对新生代,使用复制算法,用少量的内存空间换来更大的效率;针对老年代,使用标记-整理或标记-清除来处理。

  • 相关阅读:
    块级作用域
    作用域变量 var
    unkown类型
    generator (2)
    generator (1)
    generator
    索引类型
    XML 特殊字符处理和 CDATA
    15 个实用的 PHP 正则表达式
    论MySQL数据库中两种数据引擎的差别
  • 原文地址:https://www.cnblogs.com/qbzf-Blog/p/9573334.html
Copyright © 2011-2022 走看看