[总结]-第三章 垃圾收集器与内存分配策略

[总结]-第三章 垃圾收集器与内存分配策略

1、知识点

一、对象是否存活的断定

  • 引用计数法
  • 可达性分析(GC Roots)

断定对象死亡须要通过2次标记:java

  • 第一次标记:可达性分析后没有与GC Roots相链接的引用链。
  • 第二次标记:GC对F-Queue中的对象进行标记(低优先级的Finalizer线程会去执行F-Queue中对象的finalize()方法)

二、引用分类

  • 强引用(Strong Reference)
    • 主要强引用还在,则垃圾收集器不会回收被引用的对象。
  • 软引用(Soft Reference)
    • 内存不足即将OOM时,回收。好比:缓存数据。
  • 弱引用(Weak Reference)
    • 只要gc就回收。
  • 虚引用(Phantom Reference)
    • 能够判断被关联的对象是否被GC

三、finalize( )

  • 任何一个对象的finalize()方法都只会被系统自动调用一次。(注意是对象,并非类);
  • finalize()若是耗时过长,GC并不会等待。它只是通知另外一个线程(Finalizer)去执行而已;
  • 知道便可,不建议使用;

四、垃圾收集算法

  • 引用计数器
    • 优势:实时性,只要对象的引用计数器为0,马上回收;
    • 缺点:互相引用就永远没法去除。
  • 标记、清除(通常在老年代适用)
    • 标记:找到全部可访问的对象,作个标记;
    • 清除:遍历堆,把未标记的对象清除;
    • 缺点:一、标记、清除效率都低;二、空间内存碎片;三、STW;
  • 标记、整理(通常在老年代适用)
    • 标记:找到全部可访问的对象,作个标记;
    • 整理:将存活对象向一端移动,最后清除端边界之外的对象;
  • 复制(通常在新生代适用)
    • 优势:GC时,将存活的对象复制到另一半空间中,删除当前空间全部遗留对象便可。简单高效。
    • 缺点:须要浪费一半空间。
    • 衍生:Eden(1)+ Survivor(2),默认 Eden:Survivor:Survivor = 8:1:1。
  • 分代收集
    • 新生代使用复制算法;
    • 年老代使用标记清除或标记整理算法。

五、安全点和安全区域

  • 安全点:以“是否具备让程序长时间执行的特征”来选定。好比方法调用、循环跳转、异常跳转等。程序运行到安全点后会停下来进行GC;算法

  • 安全区域:线程进入SafeRegion,若是此时JVM发起GC,则无论进入安全区域的线程。在线程离开安全区域以前,检查系统是否已经完成了根节点枚举或整个GC过程。如完成,则线程继续执行,若是没完成,则必须等待。缓存

六、垃圾收集器

  • CMS(Concurrent Mark Sweep)安全

    • 定义:
      • 以获取最短回收停顿为目标的收集器;
      • 基于“标记-清除”算法。
    • 步骤:
      • 初始标记(STW):标记GC Roots能关联的对象,速度很快。
      • 并发标记:进行GC Roots Tracing(追踪)的过程,耗时较长。好在能够并发。
      • 从新标记(STW):修正并发标记期间,产生变更的那一部分对象的标记记录。
      • 并发清除:耗时较长。好在能够并发。
    • 优势:
      • 并发收集、低停顿。
    • 缺点:
      • CMS收集器对CPU资源很是敏感:CMS默认启动的回收线程数是(CPU数量+3)/4。
      • CMS收集器没法处理浮动垃圾:须要等待下一次GC时再清理。
      • 基于“标记清除”算法,会有大量空间碎片
  • G1(Garbage-First)微信

    • 定义:
      • 将整个java堆划成多个大小相等的独立区域(Region);
      • 经过维护一个优先列表,来有计划的回收价值最大的Region;
      • G1中每一个Region都有 一个与之对应的Remembered Set,存储使用此对象的引用信息。
    • 步骤:
      • 初始标记
      • 并发标记
      • 最终标记:修正在并发标记期间,产生变更的那一部分标记记录。虚拟机会将变化计入Remembered Set Logs中(并发标记期间)。最终标记须要将Remembered Set Logs 合并到Remembered Set中。
      • 筛选回收:对各个Region的回收价值和成本进行排序,根据用户指望的GC停顿时间来制定计划后开始GC。
    • 优势:
      • 并行与并发
      • 分代收集
      • 空间整合:基于标记整理或复制算法,不会有空间碎片。
      • 可预测的停顿
    • 缺点:
      • 若是应用追求吞吐量,则G1并无什么特别的好处。

七、新生代GC与老年代GC

  • 新生代GC(MinorGC):指发生在新生代的垃圾收集动做,由于Java对象大多都具有朝生夕灭的特性,因此MinorGC特别频繁,通常回收速度也比较快。并发

    • 当Eden区内存不足时,触发MinorGC。
    • 历次晋升的平均大小 < 老年代的连续空间,触发MinorGC。
  • 老年代GC(MajorGC/FullGC):指发生在老年代的GC,出现了MajorGC,常常会伴随至少一次的MinorGC。速度通常会比MinorGC慢10倍以上。.net

    • 历次晋升的平均大小 > 老年代的连续空间,触发FullGC。

只要老年代的连续空间大于新生代对象总大小或者历次晋升的平均大小就会进行MinorGC,不然将进行FullGC。线程

八、进入老年代

  • 大对象直接进入老年代对象

    • -XX:PretenureSizeThreshold参数,比此值大的会直接在老年代分配。
    • 目的是避免在Eden区及两个Survivor区之间发生大量的内存复制。
  • 长期存活的对象进入老年代排序

    • -XX:MaxTenuringThreshold默认15,每次MinorGC后,年龄+1。
  • 动态对象年龄

    • 若是在Survivor空间中相同年龄全部对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就直接进入老年代。

博客

https://my.oschina.net/gmarshal

欢迎关注个人我的微信订阅号:(听说这个头像程序猿专用)

输入图片说明

相关文章
相关标签/搜索