读书笔记。

第3章 HotSpot VM基本架构

  • VM垃圾回收器
  • JIT编译器
  • VM运行时

VM类加载:

  1. 类加载:
    • 根据给定的Java类或接口,根据名字找到Java类的二进制文件(二进制字节流),定义Java类,创建java.lang.Class对象;如果没有找到抛出NoClassDefFount异常。
    • Java类加载前,必须先加载它的所有超类或接口。
  2. 链接:
    • 检查类文件的语义、常量池符号、类型;
    • 创建静态字段初始化标准默认值(int标准值为0,而不是指定的值value=xxx),分配方法表;
  3. 初始化:
    • 初始化类,运行类构造器(首先要初始化超类,不会初始化超接口);

类加载器

首个加载器成为:初始类加载器(Initiating Class Loader),最终定义类的类加载器成为:定义类加载器(Definiting Class Loader)。

层级关系顺序:启动类加载器->扩展类加载器->系统类加载器

线程状态:

  • 新线程:线程正在初始化
  • 线程在Java中:线程正在执行Java代码
  • 线程在VM中:线程正在HotSpot VM中执行
  • 线程阻塞
  • MONITOR_WAIT:线程正在等待获取竞争的监视锁
  • CONDVAR_WAIT:线程正在等待HotSpot VM使用的内部条件变量
  • OBJECT_WAIT:线程正在执行java.lang.Object.wait()

垃圾回收器

为什么分代(弱分代假设):

  • 大多数分配对象的存活时间很短;
  • 存活时间久的对象很少引用存活时间短的对象;

2个物理区,不算永久代(用户创建的对象不会在此,是HotSpot存放元数据的地方):

  • 新生代

    • Eden:新创建的对象分配在这里(不是所有的,大的对象可能直接分在老年代,因为Eden区放不下)。Minor GC后Eden去几乎总是空的。

    • Survivor(一对:from-to):这里的对象至少经历了一次Minor GC,在提升到老年代之前还有一次被收集的机会。

      Minor GC之后,from-to交换角色。Minor GC过程中,Survivor可能不足以容纳Eden和另一个Survivor中的存活对象,多余的对象将被移到老年代,这被成为过早提升(Premature Promotion)。这会导致老年代中短期存活对象的增长,可能会引发严重的性能问题。

  • 老年代

    老年代满了(达到一定阈值)会进行Full GC.

第4章 JVM性能监控

重要的垃圾收集数据

  • 当前使用的垃圾收集器
  • Java堆的大小
  • 新生代和老年代的大小
  • 永久代的大小
  • Minor GC的持续时间
  • Minor GC的频率
  • Minor GC的空间回收量
  • Full GC的持续时间
  • Full GC的频率
  • 每个并发垃圾收集周期内的空间回收量
  • 垃圾收集前后Java堆的占用量
  • 垃圾收集前后新生代和老年代的占用量
  • 垃圾收集前后永久代的占用量
  • 是否老年代或永久代的占用触发了Full GC
  • 应用是否显示调用了System.gc()

第6章 Java应用性能分析技巧

性能优化机会

  • 使用更高效的算法
  • 减少锁争用
  • 为算法生成更有效率的代码

第7章 性能调优

性能属性

  • 吞吐量
  • 延迟
  • 内存占用

这其中任何一个属性性能的提高几乎都是以另一个或者两个属性性能的损失作代价的。很多时候,某一个或两个属性的性能比另一个更重要。

原则

JVM垃圾收集器调优有是三个基本原则:

  • Minor GC回收原则: 每次Minor GC都尽可能多的收集垃圾对象。可以减少应用Full GC的频率。Full GC的持续时间总是很长,是应用程序无法达到其延迟或吞吐量要求的罪魁祸首。
  • GC内存最大化原则:处理吞吐量和延迟问题时,垃圾处理器能使用的内存越大,即Java堆空间越大,垃圾收集的效果越好,应用程序运行也越流畅。
  • GC调优的3选2原则:在这三个属性中任意选择两个进行JVM垃圾收集器调优。