读书笔记-深入理解Java虚拟机#2

一、对象已死

  • 引用计数算法,引用加1,失效减1;为0时被回收。
  • 可达分析算法,从GC Root开始搜索,当一个对象在GC ROOT没有任何引用链则对象不可用。
  • GC ROOT 对象包括下面几种:
    1.虚拟机栈中引用的对象;
    2.方法区中类静态属性引用的对象;
    3.方法区中常量引用的对象;
    4.本地方法栈中引用的对象;

引用分为强引用,软引用,弱引用,虚引用
– 强引用指代码普遍存在,类似 Object obj = new Object(),只要强引用在永远不会被回收;
– 软引用是描述一些有用但非必须的对象,系统内存溢出异常前,会把这些对象回收;
– 弱引用是描述非必须对象,强度比软引用更弱一些,每次垃圾收集器工作时,无论内存是否够都会被回收;
– 虚引用称幽灵引用,是最弱的引用关系,设置虚引用的唯一目的是对象被回收时收到一个系统通知;

判断一个类是否是无用的类,需同时满足:

  • 该类所有实例都已经被回收;
  • 加载该类的ClassLoader已被回收;
  • 该类对应的java.lang.Class对象没有在其他地方被引用 ;

二、垃圾收集算法

标记-清除算法

  • 分为标记和清除两个阶段:首先标记处需回收对象,完成后统一回收。
  • 不足:1.效率问题 2.空间问题,清除后产生大量不连续内存碎片
    《读书笔记-深入理解Java虚拟机#2》

复制算法

  • 将内存按容量划分为大小相等的两块,每次使用其中一块,当一块用完了,将存活对象复制到另一块,并清理旧块
  • 实现简单,运行高效,但内存使用缩小一半
    《读书笔记-深入理解Java虚拟机#2》

标记-整理算法

《读书笔记-深入理解Java虚拟机#2》

分代收集算法

  • java堆分为新生代和老年代
  • 新生代选用复制算法,老年代采用标记-清理或者标记-整理算法

三、HotSpot的算法实现

枚举根节点

  • 可达性分析必须在一个能确保一致性的快照中进行–Stop-The-World。
  • 虚拟机通过OopMap的数据结构得知哪些地方存放着对象引用。

安全点

  • 在特定的位置生成OopMap,这些位置称为安全点。
  • 程序执行只有在安全点时才会暂停。
  • 安全点不能太少以致于GC等待时间太长,也不能过于频繁以致于过分增大运行负荷。
  • 安全点选定以是否具有让程序长时间执行的特征为标准,如方法调用,循环跳转,异常跳转。
  • 如何让所有线程都在安全点处停顿:抢先式中断和主动式中断
    1.抢先式中断不需要代码配合,GC时把所有线程中断,发现不在安全点处线程让其跑到安全点上中断。
    2.主动式是当需要中断时,不直接操作线程而设置一个标志,各线程主动去轮询这个标志,发现标志为真则中断挂起。

安全区域

  • 安全区域指在一段代码片段之中,引用关系不会发生变化,在这区域中任意地方GC都是安全的。

四、垃圾收集器

Serial收集器

  • 一个单线程的收集器。
  • 对于运行在Client模式下的虚拟机是个很好选择。

    ParNew收集器

  • Serial收集器的多线程版本。

  • 并行(Parallel)指多条垃圾收集器线程并行工作,此时用户线程处于等待状态。
  • 并发(Concurrent)指用户和收集器线程同时执行(可能交替执行),用户程序继续运行,收集器运行另一个CPU上。

Parallel Scavenge收集器

  • 新生代的收集器,也是使用复制算法的收集器,又是并行的多线程收集器。
  • -XX:MaxGCPauseMillis 控制最大垃圾收集器停顿时间,GC停顿时间缩短以牺牲吞吐量和新生代空间来换取的。
  • -XX:GCTimeRatio 设置吞吐量大小(0-100)。
  • -XX:+UseAdaptiveSizePolicy 打开后不需要指定新生代大小(-Xmn)、Eden与Surviror区比例等参数。

Serial Old收集器

  • Serial收集器的老年代版本。
  • 意义在于给Client模式的虚拟机使用。

    Parallel Old收集器

  • Parallel Scavenge的老年代版本。

    CMS收集器

  • 以获取最短回收停顿时间为目标的收集器,基于标记-清除算法实现。

    G1收集器

  • 面向服务端应用的垃圾收集器。

  • 将整个java堆分为多个大小相等的独立区域,新生代和老年代都是一部分区域的集合。

五、内存分配与回收策略

对象优先在Eden分配

  • 对象在新生代Eden分配,没有空间会发起一次Minor GC。
  • 新生代GC(Minor GC)指发生在新生代垃圾收集动作,非常频繁,回收速度也比较快。
  • 老年代GC(Full GC)指发生在老年代GC,比Minor GC速度慢10倍以上。

    大对象直接进入老年代

  • 大量连续占用内存的对象,典型的是长字符串以及数组。

  • -XX:PretenureSizeThreshold 令大于这个设置值的对象直接在老年代分配,避免在Eden与survivor直接内存复制。
  • 上面参数只对Serial和ParNew两款收集器有效。

长期存活的对象将进入老年代

动态对象年龄判定

空间分配担保

    原文作者:java虚拟机
    原文地址: https://blog.csdn.net/xingyadong1986/article/details/82734804
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注