读书摘录--《深入理解Java虚拟机》--part1
引言:“多读书,多看报,少吃零食,多睡觉——《风之语录》 ”
一、走近Java
p3 我们可以把Java程序设计语言,Java虚拟机、Java类库这三部分统称为JDK(Java Development Kt),JDK是用于支持Java程序开发的最小环境。
可以把Java类库API中的Java SE API子集和Java虚拟机这两部分统称为JRE(Java Runtime Environment),JRE是支持java程序运行的标准环境。
p13 而Classic VM的生命周期则相对要长不少,它在JDK1.2之前是JDK中唯一的虚拟机,在JDK1.2时,它与HotSpot VM并存。
相信所有Java程序员都听说过HotSpot虚拟机,它是Sun/Oracle JDK和Open JDK中的默认Java虚拟机.
p14 HotSpot指的是它的热点代码探测技术
如果一个方法被频繁调用,或方法中有效循环次数很多,将会分别触发标准即时编译和栈上替换编译行为。
p15 如果说HotSpot是天下第一的武林盟主,那曾经与HotSpot并称”三大商业Java虚拟机“的另外两位,毫无疑问就该是天下第二了,他们分别是BEA System公司的JRockit与IBM公司的IBM J9.
p17 Liquid VM(BEA)、Zing虚拟机(Azal)——PGC、C4收集器
p18 Dalvik虚拟机并不是一个Java虚拟机。
p20 "元循环“(Meta-Circular,是指使用语言自身来实现其运行环境)虚拟机。
JDK11时,可以认为OpenJDK与Oracle JDK代码实质上已经达到完全一致的程度。
p21 Graal VM被官方称为“Universal VM”和“Polyglot VM”,这是一个在HotSpot虚拟机基础上增强而成的跨语言全栈虚拟机。
p23 HotSpot虚拟机中含有两个即时编译器,分别是编译耗时短但输出代码优化程度较低的客户端编译器(简称C1)以及编译耗时长但输出代码优化质量也更高的服务端编译器(简称C2)
Graal编译器——C2编译器替代者
p24 提前编译(Ahead of Time Compilation,AOT)是相对于即时编译的概念,提前编译能带来的最大好处是Java虚拟机加载这些已经预编译成二进制库之后就能够直接调用,而无须再等待即时编译器在运行时将其编译成二进制机器码。
二、自动内存管理
p43 程序计数器是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器。
虚拟机栈 局部变量槽(Slot)
p44 本地方法栈 HotSpot虚拟机直接就把本地方法栈和虚拟机栈合二为一。
p45 在《Java虚拟机规范》中对Java堆的描述是:“所有的对象实例以及数组都应当在对上分配”
Java堆是垃圾收集器管理的内存区域。
Java堆既可以被实现成固定大小的,也可以是可扩展的,不过当前主流的Java虚拟机都是按照可扩展来实现的(通过-Xmx和-Xmms设定)。
p46 方法区与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据。
p48 对象的创建:“指针碰撞”、“空闲列表”
选择哪种分配方式由Java堆是否规整决定,而Java堆是否规整又由采用的垃圾收集器是否带有空间压缩整理(Compact)的能力决定。
p49 本地线程分配缓冲(Thread Local Allocation Buffer,TLAB)虚拟机是否使用TLAB,可以通过 -XX:+/-UseTLAB参数来设定。
p51 在HotSpot虚拟机里,对象在堆内存中的存储布局可以划分为三个部分:对象头、实例数据和对齐填充。
HotSpot虚拟机对象的对象头部分包括两类信息。第一类是用于存储对象自身的运行时的数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等。这部分数据的长度在32位和64位的虚拟机中分别为32个比特和64个比特,官方称为“Mark Word”。
对象头的另外一部分是类型指针,即对象指向它的类型元数据的指针。Java虚拟机通过这个指针来确定该对象是哪个类的实例。
p57 关于虚拟机栈和本地方法栈,在《Java虚拟机》中描述了两种异常:
1)如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverFlowError异常。
2)如果虚拟机的栈内存允许动态扩展,当扩展栈容量无法申请到足够的内存时,将抛出OutOfMemoryError异常。
p63 方法区的主要职责是用于存放类型的相关信息,如类名、访问修饰符。常量池、字段描述、方法描述等。