11 | 即时编译:高性能JVM的核心秘密
海纳
你好,我是海纳。
在前面的课程里,我们讲解了进程内部的具体布局,以及每一个部分的功能和作用。你会发现,所有的例子都是用 C/C++ 写的,我相信你在学习的过程中,心里可能会产生这样的疑问:那 Java 和 Python 语言是怎么运行起来的呢?
有这个疑问非常合理。我曾经讲过 C/C++ 编译的结果,它在 linux 上是 ELF 文件,在 windows 上是 exe 文件,这两种文件都可以直接被操作系统加载运行的二进制文件。另外,C/C++ 源代码也可以被编译成动态链接库文件。
而在 Java 语言里,程序员都知道 Java 源代码被 javac 编译以后,生成的是字节码文件,也就是 class 文件,而且不管编译所使用的操作系统是什么,相同的 Java 源码必然得到相同的 class 文件。class 文件显然与上面 C/C++ 编译的二进制文件都不相同,因为它与编译的平台无关。
这节课,我们就围绕着 Java 是怎么运行起来的这个问题逐层展开,在这个过程中,我会教你如何阅读和分析字节码,以及猜测它的 JIT 结果。所以通过这节课的学习,你不仅能了解到 Java 字节码的核心知识、JVM 中的解释器和 JIT 编译器的原理,而且,还能进一步理解 JVM 虚拟机。在这个基础上,你就能写出更高效、对编译器更友好的程序,而且碰到桥接方法这一类 Java 中非常抽象和难以理解的概念时,也能着手分析。
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
JIT编译器是Java虚拟机高性能的核心秘密。本文深入介绍了Java字节码的生成和执行过程,以及解释器和JIT编译器的实现原理。通过详细解释JIT编译器的运行机制和优势,包括申请可写可执行的内存区域和基于性能采样的编译优化,读者能够深入了解Java字节码的执行过程和JIT编译器的作用。文章通过实例和代码演示了如何使用mmap来申请有写权限和执行权限的内存,以及手写机器码的方式来执行即时编译。此外,文章还介绍了基于采样的编译优化和退优化,以及JIT编译器的基本原理。通过对编译器优化和JIT编译器的工作原理的深入讲解,读者可以掌握如何编写程序,以便让JIT编译器生成最高效的机器码。总之,本文为读者提供了全面的技术知识和实践经验,是一篇值得深入阅读的高级技术文章。
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《编程高手必学的内存知识》,新⼈⾸单¥59
《编程高手必学的内存知识》,新⼈⾸单¥59
立即购买
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
登录 后留言
全部留言(8)
- 最新
- 精选
- 陈狄a在栈中没有争议,怎么都说r在堆上呢?r是引用变量,也在栈中吧,ramdom对象才在堆中吧。
作者回复: 对。这题的本意其实是让大家能区分值类型和对象类型的,就没把引用说得那么清楚。你的说法是最准确的。
2021-12-2125 - 郑童文您好老师,有两个问题我不太明白: 1)原文中说:“每一个 Java 方法的栈里面都有一个模拟栈”,栈中有栈? 这个模拟栈和变量表是保存在Java方法的栈的某一个栈帧的吗?还是每个栈帧都要保存一个模拟栈和变量表? 2)请问“可执行权限”的内存区域怎么理解? 就是代码段吗?
作者回复: 1. 每个栈帧都要保存一个模拟栈和变量表。 2. 它和普通的代码段最大的不同在于,它是可写可执行的。也就是说运行时可以修改。
2021-12-081 - 送过快递的码农终于到Java了 ,发现还是有许多看不懂。我猜应该还是在堆里面吧。虽然从Java的角度来说,临时变量是应该在栈里面。但是我猜想对于C进程来说,在解释之前,进程是不知道的啊,只有执行的时候,才知道你是在Java栈还是Java堆里面,而且老师也说过,Java是模拟的栈还有变量表,那模拟栈应该是对应C的结构体吧,应该是放堆存着先?
作者回复: 你的这些问题,我们放在第19,20课会讲一些。希望你持续关注。
2021-11-18 - kylina是局部变量,存放在虚拟机的模拟栈上,但JVM会将模拟栈创建在进程虚拟内存哪里呢?猜测是栈 r是Java对象,分配到Java堆中,JVM应该提前使用mmap创建一大块内存,应该是在内存映射区吧
作者回复: 不是哦。JVM自己完全托管了。没有再借用Linux的内存布局。我后面会讲这个问题。
2021-11-17 - 李二木r是在堆上,a在虚拟机栈上?
作者回复: very good:)
2021-11-172 - 鵼终于看到java了,思考题,a是本地变量,在栈上,具体点应该是在本地变量表中,r是对象,在堆上。目前java没有栈上分配对象技术,但是是可以将对象中的属性,比如通过逃逸分析,一些对象只在方法内用,并且用到的只是对象的一些属性,是可以将对象的属性直接放到栈上的,因此可以不用创建对象。但是r因为用的是方法,虽然只在本方法用,但是java没有栈上分配对象的技术,所以还是在堆上。其实更准确点应该是在tlab上。2021-11-232
- keepgoing虽然不太熟悉Java语言,但也学到了核心知识点,👍2021-11-201
- 设置昵称遇到过单机code Cache满的问题,一直没有找到原因。能帮忙提供一下排查思路吗?2022-06-11
收起评论