如何找到native方法对应的Hotspot源码

简介: 哈喽,我是子牙。十余年技术生涯,一路披荆斩棘从技术小白到技术总监到JVM专家到创业。技术栈如汇编、C语言、C++、Windows内核、Linux内核。特别喜欢研究虚拟机底层实现,对JVM有深入研究。分享的文章偏硬核,很硬的那种。

哈喽,我是子牙。十余年技术生涯,一路披荆斩棘从技术小白到技术总监到JVM专家到创业。技术栈如汇编、C语言、C++、Windows内核、Linux内核。特别喜欢研究虚拟机底层实现,对JVM有深入研究。分享的文章偏硬核,很硬的那种。

手撸过JVM、内存池、垃圾回收算法、synchronized、线程池、NIO、三色标记算法…

erafbbd8u7.png

大家平时在看jdk源码的时候,是不是看着看着,总是会凑不及防地遇到native方法,然后就束手无策了。

image.png

今天我就教大家如何精准定位到Java方法对应的C++代码、如何高效研究Hotspot源码,甚至!教大家如何修改Hotspot源码,拓展反射API,为我所用!

怎么找

就拿线程的start方法为例吧

image.png

一、定位文件

如果是系统的native方法,都是很有规律的

start0是Thread类中的方法,Thread类在jdk中有其对应的.c文件:/openjdk/jdk/src/share/native/java/lang/Class.c

image.png

有没有看到很多你熟悉的Java类?比如System.c,里面的就是System.java中的所有native方法。

二、找方法

系统提供的JNI模块注册native方法有两种方式,所以找的话也有两种情况:

1、直接调用JVM模块中的方法,在每个.c文件的头部就可以找到

image.png

2、JNI模块中定义一个方法,直接找

image.png

3、你得理解这张远古图,才能理解JVM各模块的位置及联系

image.png

怎么读

找到native方法对应的Hotspot源码是第一步,接下来就是如何读懂的问题。

Hotspot主要是用C++编写的,所以掌握C++是必要的。对于大家来说,C++最难的应该就是它丰富的语法糖及万恶之源指针了。这些知识,只能通过做项目才能熟练掌握及深入理解。所以掌握C++是基础,你还得有C++的项目开发经验,否则你还是看不懂Hotspot源码。做什么项目?肯定不是写写常见的数据结构及算法,你得写一些与Hotspot相关的小项目,比如OOP机制、内存池、垃圾收集算法…

掌握了C++,有C++项目开发经验就可以了吗?还不够!你还得对JVM底层原理有深入的理解。这个理解不是看周志明的《深入理解Java虚拟机》就足够的,你得去看一些讲Hotspot源码级别的书籍,做到真正的理解才足够。这边给大家推荐两本:深入Hotspot、解密Java虚拟机底层原理与实现。如果你懒得找,关注公众号【硬核子牙】回复【Hotspot书】获取。

除此之外,还得掌握HSDB这款工具的使用,能熟练地用它去查找JVM内部找到你想要的数据。比如静态属性到底是在堆区还是方法区这样的问题,就可以通过HSDB查看Java类映射的Klass对象,然后通过查看它的属性得到答案。这款工具不知道怎么用?我之前讲的JVM底层原理中有演示。关注公众号【硬核子牙】回复【Hotspot书】获取。

image.png

再说下研究Hotspot源码的顺序:先把JVM的启动流程整个看一遍,这时候会碰到很多不知道干啥有啥用的类、不知道为什么存在的流程…不用管,理清主线就可以了。第二步就是去看JVM是如何执行main方法的,这个流程包含类加载的流程及JVM执行方法的流程,同样会遇到各种看不懂。不要灰心,理清主线了解个大概即可。然后就是求甚解的阶段,基于对JVM底层原理的理解仔细读类加载流程、内存初始化、垃圾收集器与内存如何构建起的桥梁、模板引擎执行流生成、封装继承多态的实现原理…这个过程可能会很久很久,所以这个过程不能急,慢慢啃。

读源码需要有单步调试环境,因为你需要看调用链路、变量赋值、指针指向,甚至是运行时代码区。我之前分享过如何搭建单步调试openjdk环境(链接在文末)。相关的软件建议与我的环境保持一致,不然你可能需要花很长时间踩坑。关注公众号【硬核子牙】回复【单步调试】获取相关软件。

image.png

黑科技

native方法也找到了,我又是C++大佬,我改怎么验证我的想法及猜测呢?改代码呗!改完后给Java提供调用API呗!JNI行吗?不行!JNI能做的事情都被Hotspot限制死了。你想做的一些事情,只有修改Hotspot源码这一招。我给大家分享一招最简单的。咱们就拓展反射的API吧。

一、增加native方法

image.png

二、实现native方法

image.png

三、让编译器知道我增加了方法

image.png

四、编译

image.png

五、运行

image.png

OK,东风已就位,可以踏上探究Hotspot源码之旅了。

我是子牙老师,喜欢钻研底层,深入研究Windows、Linux内核、JVM。如果你也喜欢研究底层,欢迎关注我的公众号【硬核子牙】

相关文章
|
27天前
|
Java 编译器 API
深入解析:JDK与JVM的区别及联系
在Java开发和运行环境中,JDK(Java Development Kit)和JVM(Java Virtual Machine)是两个核心概念,它们在Java程序的开发、编译和运行过程中扮演着不同的角色。本文将深入解析JDK与JVM的区别及其内在联系,为Java开发者提供清晰的技术干货。
29 1
|
5月前
|
JavaScript Java API
JAVA程序运行问题之JVM找到并开始执行main方法如何解决
JAVA程序运行问题之JVM找到并开始执行main方法如何解决
|
5月前
|
存储 算法 Java
JAVA程序运行问题之Java类加载到JVM中加载类时,实际上加载的是什么如何解决
JAVA程序运行问题之Java类加载到JVM中加载类时,实际上加载的是什么如何解决
|
5月前
|
前端开发 Java 编译器
Java面试题:描述Java类的加载过程,包括加载、链接、初始化等阶段。
Java面试题:描述Java类的加载过程,包括加载、链接、初始化等阶段。
34 0
|
Java 编译器
【JVM原理探索】class字节码指令方法[调用]详解(上) | Java开发实战
【JVM原理探索】class字节码指令方法[调用]详解(上) | Java开发实战
149 0
【JVM原理探索】class字节码指令方法[调用]详解(上) | Java开发实战
|
Java
JAVA中,如果发现一个值起作用,却又没找到哪里使用,检查一下是否有native/JNI中反射
JAVA中,如果发现一个值起作用,却又没找到哪里使用,检查一下是否有native/JNI中反射
88 0
|
存储 监控 安全
内存泄露的原因找到了,罪魁祸首居然是Java TheadLocal
内存泄露的原因找到了,罪魁祸首居然是Java TheadLocal
内存泄露的原因找到了,罪魁祸首居然是Java TheadLocal
|
存储 缓存 前端开发
【超硬核】JVM源码解读:Java方法main在虚拟机上解释执行
【超硬核】JVM源码解读:Java方法main在虚拟机上解释执行
【超硬核】JVM源码解读:Java方法main在虚拟机上解释执行
|
算法 Java Linux
JDK核心JAVA源码解析(5) - JAVA File MMAP原理解析(下)
JDK核心JAVA源码解析(5) - JAVA File MMAP原理解析(下)

热门文章

最新文章