《深入理解JVM》读书笔记

时间:2023-02-15 10:01:24

内存模型

程序计数器
  • 当前线程所执行的字节码的行号指示器,线程私有。字节码解析器的工作是通过改变这个计数器的值,来选取下一条需要执行的字节码指令。
java虚拟机栈
  • 线程私有,生命周期与线程相同。
  • Java方法执行的内存模型。每个方法创建一个栈帧,包含局部变量表,操作数栈等。
  • 局部变量表存储编译期可知的基本数据类型,对象引用类型
本地方法栈
  • 为native本地方法服务,与虚拟机栈类似。
java堆
  • 所有线程共享
  • 存放对象实例
  • 垃圾收集重要区域,可以分为新生代和老年代,Eden、From Survivor和To Survivior
方法区
  • 所有线程共享
  • 存储虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
  • 包含运行时常量池, class文件中存放的字面量和符号引用,类加载后进入运行时常量池存放。运行时常量池具备动态性,不止编译期产生的常量可以存放,运行期也可以存储。
  • HotSpot使用永久代来实现方法区,垃圾回收主要针对常量池回收和类的卸载。JDK1.8后,采用元数据区实现方法区的作用。

对象创建

内存分配
  • 指针碰撞
  • 空闲列表

垃圾收集机制

概念
  • Minor GC:指发生在新生代的垃圾收集动作,新生代Eden区满触发。
  • Full GC:同时回收新生代、老年代,触发条件多:
  • 调用System.gc时,系统建议执行Full GC,但是不必然执行
  • 老年代空间不足
  • 方法区空间不足
  • 通过Minor GC后进入老年代的平均大小大于老年代的可用内存
  • Minor GC发生时分配担保失败
  • Stop The World:分析期间执行系统对象引用关系保持固定。
  • 安全点:程序执行时并非所有地方都能停顿下来开始GC,只有到达安全点时才可以暂停。
  • 安全区域:在一段代码片段中,引用关系不会发生变化。安全区域任意地方开始GC都是安全的。
确定回收对象
  • 引用计数法,简单高效,存在循环引用问题
  • 可达性分析,选定根节点并向下搜索,当对象和根节点之间没有引用链时,则此对象不可达
    根节点包括:
    • 虚拟机栈(栈帧中的本地变量表)中引用的对象
    • 方法区中静态属性引用的对象
    • 方法区常量引用的对象
    • 本地方法栈中JNI(Native方法)引用的对象
引用的概念

引用分为强引用、软引用、弱引用和虚引用,强度依次减弱。

  • 强引用,代码中“Object obj = new Object()”这类引用,垃圾收集器不回收强引用对象。
  • 软引用,系统将要内存溢出前会进行回收。
  • 弱引用,关联对象会在下一次垃圾收集中回收。
  • 虚引用,不影响对象生存周期,目的是对象回收时,能收到系统通知。
两次标记过程
  1. 第一次标记,对象可达性分析后,没有与根节点相连的引用链。
  2. 筛选一次标记对象是否有必要执行finalize()方法,对象没有覆盖finalize()或者已经执行过finalize(),则此对象不需要执行。
  3. 需要执行finalize()的对象置入F-Queue中,并执行方法,finalize()中对象要与引用链上的对象建立连接,这是对象拯救自己被回收的最后一次机会。
  4. 第二次标记,F-Queue中没有自救的对象会被二次标记并回收。
  5. 对象的finalize()只会被系统自动调用一次,只有一次自救的机会 。
垃圾回收算法
  1. 标记清除算法
  2. 复制算法
  3. 标记整理算法
  4. 分代收集算法
垃圾收集器
  1. Serial:新生代收集器。单线程,工作时必须停止其它线程(Stop the world),采用复制算法。

  2. ParNew:Serial的多线程版本,同样需要暂停用户所有进程。

  3. Parallel Scavenge:新生代收集器,采用复制算法,并行多线程。特点是可控制吞吐量,有GC自适应调节策略,是与ParNew的重要区别。

  4. Serial Old:Serial的老年代版本

  5. Parallel Old:Parallel Scavenge的老年代版本,多线程和标记整理算法

  6. CMS:老年代收集器,以获取最短回收停顿时间为目标,基于标记清除算法。四个阶段,初始标记和重新标记要“Stop the world”:初始标记、并发标记、重新标记、并发清除。耗时最长的并发标记和并发清除过程可以与用户一起工作。

    缺点:1.对CPU资源敏感。 2. 无法处理浮动垃圾 3. 基于标记清除算法

  7. G1:基于标记整理算法,并行与并发,分代收集,空间整理,可预测的停顿。堆内存被划分为多个大小相等的内存块(Region)。使用Remembered Set来避免全堆扫描。初始标记、并发标记、最终标记、筛选回收。