![](https://img-blog.csdnimg.cn/20190918140129601.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
HotSpot JVM 源码分析
文章平均质量分 90
记录 JDK、HotSpot 工作使用。
0x13
coding...
展开
-
【Hotspot】 JNI/JNA调用、Native调用
因为前面 Java Static 中调用的 RegisterNatives 函数用于 JNI 注册,而底层调用的 Java_java_lang_Xxxx_registerNatives() 这些函数本身也是一个 JNI ,那么这些起始的 JNI 函数就是通过 NativeLookup::lookup() 进行注册的。native 是与C++联合开发的时候用的!JNA(Java Native Access)框架是一个开源的Java框架,是SUN公司主导开发的,建立在经典的JNI的基础之上的一个框架。原创 2023-04-26 17:20:36 · 1320 阅读 · 0 评论 -
【Hotspot】类生命周期(4):对象引用管理:HandleMark 和 HandleArea
(new 出来的对象的实例存储在堆中,但是仅仅存储的是成员变量,也就是平时所说的实例变量,成员变量的值则存储在常量池中。成员方法被存储在方法区,并不是存储在第一个创建的对象中,因为那样的话,第一个对象被回收,后面创建的对象也就没有方法引用了。与堆一样,是被线程共享的内存区域,要注意线程安全问题。在HandleMark的析构函数中会将HandleArea的当前内存地址到方法调用前的内存地址top之间的所有分配的oop都销毁掉,然后恢复当前线程的HandleArea的内存地址top到方法调用前的状态。原创 2023-04-25 11:28:25 · 199 阅读 · 0 评论 -
【Hotspot】类生命周期(3):对象创建 new 关键字
也就是说,Java中每个线程都会有自己的缓冲区称作TLAB(Thread-local allocation buffer),每个TLAB都只有一个线程可以操作,TLAB结合bump-the-pointer技术可以实现快速的对象分配,而不需要任何的锁进行同步,也就是说,在对象分配的时候不用锁住整个堆,而只需要在自己的缓冲区分配即可。在一般应用中,不会逃逸的局部对象所占的比例很大,如果能使用栈上分配,那大量的对象就会随着方法的结束而自动销毁了,无须通过垃圾收集器回收,可以减小垃圾收集器的负载。原创 2023-04-25 11:27:06 · 91 阅读 · 0 评论 -
【Hotspot】类生命周期(2):类解析、类链接:Oop和Klass机制
oop 指的是 Ordinary Object Pointer(普通对象指针,指向被创建的对象),它用来表示对象的实例信息,看起来像个指针实际上是藏在指针里的对象;也就是说 oopDesc 是所有对象类的顶级基础类,Java 所有对象都转换为 C++ 下 oopDesc 类对象,以此通过 C++ 方法来访问 Java 对象。HotSpot的解决方案是,为每一个已加载的Java类创建一个instanceKlass对象,用来在JVM层表示Java类。是 JVM 的规范,所有虚拟机 必须遵守的。原创 2023-04-25 11:24:40 · 454 阅读 · 0 评论 -
【Hotspot】类生命周期(1):类加载 Bootstrap 以及双亲委托
这个ClassLoader类是用C++/C语言编写的,负责将/lib目录、-Xbootclasspath选项指定的目录或系统属性sun.boot.class.path指定的目录下的核心类库加载到内存中。扩展类加载器由sun.misc.Launcher$ExtClassLoader类 Java 实现,负责将/lib/ext目录或者由系统变量-Djava.ext.dir所指定的目录中的类库加载到内存中。JVM在运行时,需要一种用来标识Java内部类型的机制。原创 2023-04-25 11:19:55 · 293 阅读 · 0 评论 -
【hotspot】执行字节码指令流程(4):编译器C1/C2
在HotSpot VM 中,除了模板解释器外,有很多地方也会用到运行时机器代码生成技术,如广为人知的C1编译器产出、C2编译器产出、C2I/I2C 适配器代码片段、解释器到JNI适配器的代码片段等。C2即时编译器采用了激进乐观的优化技术,并采用传统编译器许多的编译优化手段,如内联优化、全局值编码(GVN)、图着色的寄存器分配、BURS指令选择算法等。接着进行平台无关优化并生成平台相关的 MachNode图:最后进行平台相关优化,包括指令选择、代码重排、寄存器分配、窥孔优化,直至输出目标机器代码。原创 2023-04-25 11:17:20 · 442 阅读 · 0 评论 -
【Hotspot】执行字节码指令流程(3):编译任务队列/热点统计
其中 _goto d调用了 branch 指令就用于 for、分支跳转等,而即使编译并执行OSR(用编译后的本地代码替换掉原来的字节码指令,所谓的栈上替换就是替换调用入口地址,将原来解释器上的变量,monitor等迁移到编译后的本地代码对应的栈帧中)这一部分逻辑就在 branch 实现中。0 -> (3->2) -> 4,这种情形下已经把方法加入到3的编译队列中了,但是C1队列太长了导致在0的时候就开启了profile,然后就调整了编译策略按level 2来编译,即时还是3的队列中,这样编译更快。原创 2023-04-25 11:11:41 · 208 阅读 · 0 评论 -
【Hotspot】执行字节码指令流程(2):解释器(TemplateInterpreter/C++)
entry_table 属性是一个 entry_point 数组,按照 MethodKind 类型保存入口点,例如普通方法的入口点为_entry_table[0]、同步的普通方法的入口点为_entry_table[1],这些_entry_table[0],_entry_table[1]指向的就是之前_code队列里面的例程。模板解释器就继承自抽象解释器,在那些例程之上还有自己的特设例程,例如上面定义的一些属性,保存了程序异常时的入口例程,其实还有许多为保存例程入口而定义的字段或数组。原创 2023-04-25 11:07:51 · 385 阅读 · 0 评论 -
【Hotspot】 执行字节码指令流程(1):堆栈的创建以及Java函数调用
Stub代码是HotSpot生成的固定调用点的代码。* 将一个常量加载到操作数栈: bipush, sipush, ldc, ldc_w, ldc2_w, aconst_null, iconst_m1, iconst_i, lconst_l, fconst_f, dconst_d;注意按照后缀就知道,JVM会根据不同的操作系统使用的cpu指令集来调用不同的实现,例如这里的x86_64所对应的源文件 hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp。原创 2023-04-25 11:04:17 · 343 阅读 · 0 评论 -
【Hotspot】线程 Thread 创建到执行 thread_entry
每个 Java 中的 Thread.java 对象的创建,会在 C++ 中创建 JavaMethod 对象,并且调用系统内核线程创建的函数创建系统线程。而对于不同的操作系统来说,它们本身的设计思路基本上是完全不一样的,因此它们各自对于线程的设计也存在种种差异,所以 JVM 中明确声明了:虚拟机中的线程状态,不反应任何操作系统中的线程状态。前面已经分析了栈帧的内存结构,Java 函数的调用,以及JVM的初始化流程,会发现里面都穿插了线程,一个函数的调用就必定有线程的创建以及线程栈帧的创建。原创 2023-04-25 10:57:19 · 223 阅读 · 0 评论 -
【Hotspot】JVM启动流程
jdk/src/share/bin/java.c InitializeJVM() => 初始化jvm,调用CreateJavaVM进行初始化,调用libjvm中的库函数JNI_CreateJavaVM。hotspot/src/share/vm/prims/jni.cpp JNI_CreateJavaVM() => 进入jvm初始化阶段,Threads::create_vm()执行入口。到这一步就进入了jvm运行真正的入口。原创 2023-04-25 10:53:42 · 691 阅读 · 0 评论 -
【Hotspot】clion调试 openjdk
ubuntu20比较新, 编译openjdk8需要安装老版本的编译工具。在编译 openjdk 时还需要一个 jdk 环境用以引导。1.下载oracle-jdk8。2.下载openjdk8源码。配置多版本gcc控制。原创 2023-01-30 21:38:44 · 612 阅读 · 0 评论