图片HotSpot解释器代码片段// 确保常量池中存放的是已解释的类 if (! SET_STACK_OBJECT(result, 0); UPDATE_PC_AND_TOS_AND_CONTINUE(3, 1); } } } 本文参考于 周志明-《深入理解Java虚拟机-JVM
一、选项的分类 Hotspot JVM提供以下三大类选项: 1. 标准选项:这类选项的功能是很稳定的,在后续版本中也不太会发生变化,即使有变化也必须保证向后兼容。 指定JVM的类型:-server,-client Hotspot JVM有两种类型,分别是server和client。它们的区别是Server VM的初始堆空间会大一些,默认使用并行垃圾回收器。 在Hotspot JVM中,新生代进一步被分成了三个区域:一个稍大的区域Eden和两个较小但大小相等的Survivor区域(分别叫From和To)。 Parallel Scavenge 在Hotspot JVM中,侧重于吞吐量的垃圾回收器是Parallel Scavenge,它的相关配置如下: -XX:+UseParallelOldGC 表示新生代和老年代都使用并行回收器 参考博文: 1.https://www.zybuluo.com/jewes/note/57352 Java程序员必学的Hotspot JVM选项 2. https://blog.csdn.net/qq_
Serial收集器是HotSpot虚拟机运行在Client模式下的默认新生代收集器。
前两篇《JVM入门——运行时数据区》《JVM常见垃圾回收算法》所提到的实际上JVM规范以及常用的垃圾回收算法,具体的JVM实现实际上不止一种,有JRockit、J9等待,当然最有名当属HotSpot JVM。 下面是HotSpot JVM的整体架构图,本文着重介绍HotSpot中的垃圾回收器(Garbage Collector)。 ? 现有的HotSpot垃圾回收器以及之间的关系和应用范围如下图所示: ? 当然Serial GC在如今的HotSpot JVM中Server模式下已经几乎废弃。另外,它工作使用垃圾回收的“复制算法”工作在Java堆的新生代。
在该方法里会执行虚拟机的初始化,获取Java程序主类及main方法,然后通过JNI调用main方法, 自此,整个JVM进程执行结束,最终退出。 InitializeJVM(&vm, &env, &ifn)) { JLI_ReportErrorMessage(JVM_ERROR1); exit(1); }
需要提前了解的知识: JVM内存模型 JVM垃圾回收算法 HotSpot虚拟机所有的垃圾收集器如下图: HotSpot 所有垃圾收集器 上面有7种收集器,分为部分,上面为新生代收集器,下面是老年代收集器 Java中一种全局暂停现象,全局停顿,所有Java代码停止,native代码可以执行,但不能与JVM交互。 是Jvm client模式下默认的新生代收集器。对于限定单个CPU的环境来说,Serial收集器由于没有线程交互的开销,专心做垃圾收集自然可以获得最高的单 线程收集效率。
对象创建 对象内存布局 在HotSpot虚拟机里,对象在堆内存中的存储布局可以分为三部分:对象头、实例数据、对齐填充。 对象头 HotSpot虚拟机对象的对象头部分包含两类信息: 第一部分是用于存储对象自身的运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等,称之为 由于HotSpot VM的自动内存管理系统要求对象起始地址必须是8字节的整数倍,即对象的大小必须是8字节的整数倍。
Klass的继承关系图 oopDesc的继承关系图 oop与oopDesc的关系图 ---- JVM中,Klass代表一个Java类,oopDesc代表一个Java对象(其实只代表其头部信息),oop Klass的子类中,InstanceKlass代表一个普通的Java类(比如我们自定义的一个Java类),ArrayKlass代表数组类型的Java类(该Java类是JVM内部自动创建的,由数组维数和数组基础类型唯一确定 由于JVM内部会对这三个Java类做特殊处理,所以内部也提取出了对应的InstanceKlass类。 ---- 当JVM加载或定义一个Java类时,它会在内部创建一个对应的Klass对象,用来存放该Java类的各种信息。 通过以上几个问答,现在我们可以比较清楚的知道,在Java类加载或定义过程中,会创建一个Klass对象,作为该Java类在JVM内部的代表,同时也会创建一个java.lang.Class类型的Java对象
1.2 如何高效查找引用链 目前主流 JVM 使用的都是准确式垃圾收集,因此虚拟机有办法直接知道哪些地方存放着对象的引用。而 HotSpot 是使用一组称为 OopMap 的数据结构来实现的。 HotSpot 使用内存保护陷阱的方式,通过一条汇编指令来完成安全点轮询和触发线程中断。 2.4 优缺点 安全点机制保证了程序执行时,在不太长的时间内就会遇到可进入垃圾收集过程的安全点。 如何变脏:HotSpot 虚拟机是通过写屏障实现的。 下面介绍什么是写屏障。 5. JDK 7 之后,HotSpot 虚拟机增加了如下参数来决定是否开启卡表更新的判断条件: # 是否开启卡表更新的判断条件 -XX:+UseCondCardMark 6. 这两种方案都有在用:在 HotSpot 虚拟机中,CMS 是基于增量更新来做并发标记的,G1、Shenandoah 则是用原始快照实现的。
本JVM系列 以阅读周志明 博士的 《深入理解 Java 虚拟机》一书的笔记为蓝本,汇集一些阅读过程中找到的解惑资料而成。有的有兴趣的可以去购买原书中查看。 对象的内存布局 在HotSpot虚拟机中,对象内存中存储的布局可分为3块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。 参考资料 1、【Java对象解析】不得不了解的对象头 2、JVM源码分析之java对象头实现 类型指针 对象头的另外一部分是类型指针,即对象指向他的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例 由于HotSpot VM的自动内存管理系统要求对象起始地址必须是8字节的倍数,换句话说,就是对象的大小必须是8字节的整数倍。 Sun HotSpot使用的直接指针的方式进行对象访问的,但从整个软件开发的范围来看,各种使用语言和框架使用句柄来访问的情况也十分常见。
本文介绍JVM垃圾回收算法的具体实现,介绍各个术语,并图文并茂介绍具体的实现细节。 5、安全点 在OopMap的协助下,HotSpot可以快速准确地完成GC Roots枚举。 执行指令后,在特定位置记录OopMap信息,这些位置成为安全点。 9、卡页 hotSpot中每个卡页都是512字节,每个卡页包含不止一个对象,只要有一个存在跨代指针,那么卡表的数组元素的值则为1,成为变脏,否则为0。
HotSpot 算法实现在 JVM 中的应用摘要HotSpot 是一种常见的 Java 虚拟机 (JVM) 实现,广泛应用于 Java 开发和运行环境中。 HotSpot 的成功得益于其优秀的算法实现,本文将重点介绍 HotSpot 在 JVM 中的算法实现,包括垃圾回收、即时编译和性能优化等方面的内容。 JVM 扮演着将 Java 程序编译成可执行代码并运行的关键角色。HotSpot 作为 JVM 实现的一种,是由 Oracle 公司开发并广泛使用的。 HotSpot 在 JVM 中的算法实现对于优化性能和提升执行效率起到了至关重要的作用。 垃圾回收算法垃圾回收是 JVM 中的一个重要组成部分,它负责在运行时自动回收不再使用的对象,并回收所占用的内存资源。HotSpot 在垃圾回收算法上采用了分代回收策略,将堆内存分为年轻代和老年代。
1、根节点枚举 前面讲到了可以作为根节点的对象,但如果需要去遍历寻找这些对象的话成本就太高了,并且这个过程是会造成 STW 的,因此需要一种更高效的枚举手段; HotSpot 中采用一组 OopMap 数据结构记录对象的引用情况,在类加载完成后 HotSpot 会记录下对象中属性的偏移量和类型,在即时编译阶段会在特定位置记录下对象引用情况,OopMap 就是用来记录这两部分内容的,后面扫描时直接找到这些对象作为 一种方案是检测到垃圾收集则马上暂停线程,如果有线程不在安全点上则让它继续走到上面再中断,这种方式几乎没有 JVM 在用; 另一种是在安全点处打上标记,线程不断轮询该标记的真假,待该标记为真时,线程走到最近的安全区主动暂停 这里轮询操作在 HotSpot 中是使用了 内存保护陷阱 方式,如果此时需要暂停用户线程则虚拟机会将轮询指令所在内存页设置为不可访问,当线程访问到这里时会产生一个自陷异常信号,在预先注册的异常处理器中挂起线程等待
我们不能直接说哪个方法是内置方法,因为不同的JVM是不同的。 02 兼容性 内置方法是在需要的时候才会使用的,如果在不需要的时候则会回退到普通的方法实现,也就是java代码的实现。 他们的区别在于JVM的实现。 03 java语义的扩展 有些方法用普通的java代码是无法实现的。 Hotspot VM中的内置方法 那么对于Hotspot VM来说,内置的方法有哪些呢? 在Hotspot VM中其实有3中编译器。 第一种就是javac将java源代码编译成为字节码。 答案是可以,不过需要修改底层的JVM实现。 这里有两个具体的例子,感兴趣的大家可以自行研究。
在JDK 1.2时,它与HotSpot VM并存,而在JDK 1.3时,HotSpot VM成为默认虚拟机,直到JDK 1.4的时候,Classic VM才完全退出商用虚拟机的历史舞台。 1999年4月27日,HotSpot虚拟机发布,HotSpot最初由一家名为“Longview Technologies”的小公司开发,因为HotSpot的优异表现,这家公司在1997年被Sun公司收购了 ,占用更大的内存 C2重量级编译器,更彻底的优化 能提供更好的性能,适合生产部署 HotSpot JVM Architecture HotSpot JVM 主要包括3个组件: Class Loader 在Oracle 的HotSpot JVM里,方法区被称为永久区或者永久代(PermGen)。是否对方法区进行垃圾回收对JVM的实现是可选的。 下面,基于JDK1.7 Update14之后的HotSpot虚拟机讨论收集器。
理解 HotSpot JVM 中的不同垃圾回收器(如 CMS、G1 和 ZGC)的区别,需要深入了解它们的设计原理、工作方式和应用场景。 你可以通过 JVM 参数指定使用哪种垃圾回收器。 java -XX:+UseG1GC -Xms512m -Xmx512m GCDemo使用 ZGCsh复制代码java -XX:+UseZGC -Xms512m -Xmx512m GCDemo观察和分析通过 JVM
不一定所有虚拟机都有 如果对象是Java数组,还有一块用于记录数组长度的数据 2.2 实例数据 父类中继承和子类中定义的,都有记录 HotSpot虚拟机把相同宽度的字段分配到一起 在满足前面一个条件的情况下 父类中定义的变量会在子类之前 如果CompactFiles参数为true(默认为true),子类中较窄的变量也可能会插到父类变量的空隙中 2.3 对齐填充 不一定必然存在 没有特别含义,仅起到占位符的作用 HotSpot HotSpot采用这种方式进行对象访问
HotSpot虚拟机提供了多种垃圾收集器,每种收集器都有各自的特点,没有最好的垃圾收集器,只有最适合的垃圾收集器。我们可以根据自己实际的应用需求选择最适合的垃圾收集器。
本文当然不是要去“深入理解Java虚拟机”,JVM发展这么多年,已有非常非常多关于它的权威的书籍、文章、视频,虽然大都是一看就会,一做就废… 本文非常轻松,问自己这个问题:“JVM除了HotSpot,你还知道哪些 它是Java程序的运行平台,是二进制字节码的运行环境,它有很多发行的商用版本,其中最著名的当属Oracle官方发行的,也是JDK默认的HotSpot。 JVM发展到今天,早已不是只为Java服务。 HotSpot VM(武林盟主) 这是一个目前使用范围最广的Java虚拟机,它是Oracle JDK和OpenJDK的默认JVM,是聊天时没有特殊指定时的缺省JVM。 JRockit和HotSpot都遵循JVM规范抽象只是是侧重点不同,Oracle最终决定将二者整合(合并),且名称仍叫HotSpot。 都安装的HotSpot。
前言 上篇文章介绍了Java虚拟机的运行时数据区域,大致明白了Java虚拟机内存模型的概况,下面就基于实用优先的原则,以最常用的虚拟机HotSpot和最常用的内存区域Java堆为例,升入探讨一下HotSpot 对象的内存布局 在HotSpot虚拟机里,对象在堆内存中的存储布局可以划分为三个部分:对象头(Header)、实例数据(Insetance Data) 和对齐填充(Padding)。 对象头 HotSpot虚拟机对象的对象头包括两类信息。 第一类是用于存储对象自身运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标志等。 对齐填充 由于HotSpot虚拟机的自动内存管理系统要求对象起始地址必须是8字节的整数倍,换句话说就是任何对象的大小都必须是8字节的整数倍。