编程高手必学的内存知识
海纳
华为编译器高级专家,原 Huawei JDK 团队负责人
20674 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 33 讲
编程高手必学的内存知识
15
15
1.0x
00:00/00:00
登录|注册

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
立即购买
登录 后留言

全部留言(8)

  • 最新
  • 精选
  • 陈狄
    a在栈中没有争议,怎么都说r在堆上呢?r是引用变量,也在栈中吧,ramdom对象才在堆中吧。

    作者回复: 对。这题的本意其实是让大家能区分值类型和对象类型的,就没把引用说得那么清楚。你的说法是最准确的。

    2021-12-21
    2
    5
  • 郑童文
    您好老师,有两个问题我不太明白: 1)原文中说:“每一个 Java 方法的栈里面都有一个模拟栈”,栈中有栈? 这个模拟栈和变量表是保存在Java方法的栈的某一个栈帧的吗?还是每个栈帧都要保存一个模拟栈和变量表? 2)请问“可执行权限”的内存区域怎么理解? 就是代码段吗?

    作者回复: 1. 每个栈帧都要保存一个模拟栈和变量表。 2. 它和普通的代码段最大的不同在于,它是可写可执行的。也就是说运行时可以修改。

    2021-12-08
    1
  • 送过快递的码农
    终于到Java了 ,发现还是有许多看不懂。我猜应该还是在堆里面吧。虽然从Java的角度来说,临时变量是应该在栈里面。但是我猜想对于C进程来说,在解释之前,进程是不知道的啊,只有执行的时候,才知道你是在Java栈还是Java堆里面,而且老师也说过,Java是模拟的栈还有变量表,那模拟栈应该是对应C的结构体吧,应该是放堆存着先?

    作者回复: 你的这些问题,我们放在第19,20课会讲一些。希望你持续关注。

    2021-11-18
  • kylin
    a是局部变量,存放在虚拟机的模拟栈上,但JVM会将模拟栈创建在进程虚拟内存哪里呢?猜测是栈 r是Java对象,分配到Java堆中,JVM应该提前使用mmap创建一大块内存,应该是在内存映射区吧

    作者回复: 不是哦。JVM自己完全托管了。没有再借用Linux的内存布局。我后面会讲这个问题。

    2021-11-17
  • 李二木
    r是在堆上,a在虚拟机栈上?

    作者回复: very good:)

    2021-11-17
    2
  • 终于看到java了,思考题,a是本地变量,在栈上,具体点应该是在本地变量表中,r是对象,在堆上。目前java没有栈上分配对象技术,但是是可以将对象中的属性,比如通过逃逸分析,一些对象只在方法内用,并且用到的只是对象的一些属性,是可以将对象的属性直接放到栈上的,因此可以不用创建对象。但是r因为用的是方法,虽然只在本方法用,但是java没有栈上分配对象的技术,所以还是在堆上。其实更准确点应该是在tlab上。
    2021-11-23
    2
  • keepgoing
    虽然不太熟悉Java语言,但也学到了核心知识点,👍
    2021-11-20
    1
  • 设置昵称
    遇到过单机code Cache满的问题,一直没有找到原因。能帮忙提供一下排查思路吗?
    2022-06-11
收起评论
显示
设置
留言
8
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部