深入拆解 Java 虚拟机 / Oracle 高级研究员手把手带你入门 JVM
郑雨迪
Oracle 高级研究员,计算机博士
 
  • 课程目录
  • 课程介绍
  • 开篇词 | 为什么我们要学习Java虚拟机?

    我希望借由这个专栏,帮助你理解Java虚拟机的运行机制,掌握诊断手法和调优方式。最重要的,是激发你学习技术的热情。

  • 01 | Java代码是怎么运行的?

    作为一名 Java 程序员,你应该知道,Java 代码有很多不同的运行方式。

  • 02 | Java的基本类型

    Java引进了八个基本类型,来支持数值计算。这么做的原因主要是工程上的考虑,因为使用基本类型,能够在执行效率以及内存使用两方面提升软件性能。

  • 03 | Java虚拟机是如何加载Java类的?

    无论是直接生成的数组类,还是加载的类,Java虚拟机都需要对其进行链接和初始化。接下来,我会详细给你介绍一下每个步骤具体都在干些什么。

  • 04 | JVM是如何执行方法调用的?(上)

    在Java中,方法存在重载以及重写的概念,重载指的是方法名相同而参数类型不相同的方法之间的关系,重写指的是方法名相同并且参数类型也相同的方法之间的关系。

  • 05 | JVM是如何执行方法调用的?(下)

    虚方法调用有两种指令。如果这两种指令所声明的目标方法被标记为final,那么Java虚拟机会采用静态绑定。

  • 06 | JVM是如何处理异常的?

    异常处理的两大组成要素是抛出异常和捕获异常。这两大要素共同实现程序控制流的非正常转移。

  • 【工具篇】 常用工具介绍

    在前面的文章中,我曾使用了不少工具来辅助讲解,那么今天我便统一做一次具体的介绍。

  • 07 | JVM是如何实现反射的?

    反射是Java语言中一个相当重要的特性,它允许正在运行的Java程序观测,甚至是修改程序的动态行为。

  • 08 | JVM是怎么实现invokedynamic的?(上)

    方法句柄是一个强类型的、能够被直接执行的引用。它仅关心所指向方法的参数类型以及返回类型,而不关心方法所在的类以及方法名。

  • 09 | JVM是怎么实现invokedynamic的?(下)

    今天,我便来正式地介绍invokedynamic指令,讲讲它是如何生成调用点,并且允许应用程序自己决定链接至哪一个方法中的。

  • 10 | Java对象的内存布局

    常见的new语句会被编译为new指令,以及对构造器的调用。每个类的构造器皆会直接或者间接调用父类的构造器,并且在同一个实例中初始化相应的字段。

  • 11 | 垃圾回收(上)

    Java虚拟机中的垃圾回收器采用可达性分析来探索所有存活的对象。它从一系列GC Roots出发,边标记边探索所有被引用的对象。

  • 12 | 垃圾回收(下)

    Java虚拟机将堆分为新生代和老年代,并且对不同代采用不同的垃圾回收算法。

  • 13 | Java内存模型

    Java内存模型通过定义了一系列的happens-before操作,让应用程序开发者能够轻易地表达不同线程的操作之间的内存可见性。

  • 14 | Java虚拟机是怎么实现synchronized的?

    Java虚拟机中synchronized关键字的实现,按照代价由高至低可分为重量级锁、轻量级锁和偏向锁三种。

  • 15 | Java语法糖与Java编译器

    Java编译器将选取该泛型所能指代的所有类中层次最高的那个,作为替换泛型的具体类。

  • 16 | 即时编译(上)

    即时编译是由方法调用计数器和循环回边计数器触发的。在使用分层编译的情况下,触发编译的阈值是根据当前待编译的方法数目动态调整的。

  • 17 | 即时编译(下)

    今天我会介绍Java虚拟机的profiling以及基于所收集的数据的优化和去优化。

  • 18 | 即时编译器的中间表达形式

    即时编译器将所输入的Java字节码转换成SSA IR,以便更好地进行优化。

  • 19 | Java字节码(基础篇)

    Java方法的栈桢分为操作数栈和局部变量区。通常来说,程序需要将变量从局部变量区加载至操作数栈中,进行一番运算之后再存储回局部变量区中。

  • 20 | 方法内联(上)

    方法内联是指,在编译过程中,当遇到方法调用时,将目标方法的方法体纳入编译范围之中,并取代原方法调用的优化手段。

  • 21 | 方法内联(下)

    完全去虚化通过类型推导或者类层次分析,将虚方法调用转换为直接调用。它的关键在于证明虚方法调用的目标方法是唯一的。

  • 22 | HotSpot虚拟机的intrinsic

    HotSpot虚拟机将对标注了`@HotSpotIntrinsicCandidate`注解的方法的调用,替换为直接使用基于特定CPU指令的高效实现。

  • 23 | 逃逸分析

    即时编译器判断对象逃逸的依据有两个:一是看对象是否被存入堆中,二是看对象是否作为方法调用的调用者或者参数。

  • 24 | 字段访问相关优化

    即时编译器将沿着控制流缓存字段存储、读取的值,并在接下来的字段读取操作时直接使用该缓存值。

  • 25 | 循环优化

    循环展开是一种在循环中重复多次迭代,并且相应地减少循环次数的优化方式。

  • 26 | 向量化

    向量化优化借助的是CPU的SIMD指令,即通过单条指令控制多组数据的运算。它被称为CPU指令级别的并行。

  • 27 | 注解处理器

    注解处理器主要有三个用途。一是定义编译规则,并检查被编译的源文件。二是修改已有源代码。三是生成新的源代码。

  • 28 | 基准测试框架JMH(上)

    性能基准测试框架JMH是OpenJDK中的其中一个开源项目。它内置了许多功能,来规避由Java虚拟机中的即时编译器或者其他优化对性能测试造成的影响。

  • 29 | 基准测试框架JMH(下)

    今天我将介绍的是基准测试框架JMH的进阶功能。@Fork允许开发人员指定所要Fork出的Java虚拟机的数目。

  • 30 | Java虚拟机的监控及诊断工具(命令行篇)

    今天,我们来一起了解一下JDK中用于监控及诊断工具。本篇中我将使用刚刚发布的Java 11版本的工具进行示范。

  • 31 | Java虚拟机的监控及诊断工具(GUI篇)

    eclipse MAT可用于分析由jmap命令导出的Java堆快照。Java Mission Control是Java虚拟机平台上的性能监控工具。

  • 32 | JNI的运行机制

    Java中的native方法的链接方式主要有两种。一是按照JNI的默认规范命名所要链接的C函数,并依赖于Java虚拟机自动链接。另一种则是在C代码中主动链接。

  • 33 | Java Agent与字节码注入

    我们可以通过Java agent的类加载拦截功能,修改某个类所对应的byte数组,并利用这个修改过后的byte数组完成接下来的类加载。

  • 34 | Graal:用Java编译Java

    GraalVM是一个高性能的、支持多种编程语言的执行环境。

  • 35 | Truffle:语言实现框架

    Truffle是一个语言实现框架,允许语言开发者在仅实现词法解析、语法解析以及AST解释器的情况下,达到极佳的性能

  • 36 | SubstrateVM:AOT编译框架

    SubstrateVM的设计初衷是提供一个高启动性能、低内存开销,和能够无缝衔接C代码的Java运行时。它是一个独立的运行时,拥有自己的内存管理等组件。

  • 尾声 | 道阻且长,努力加餐

    最后,感谢一路以来的陪伴与支持,谢谢你,我们后会有期!

作为开发工程师,你也许会在日常编程中被Java的启动性能和内存耗费所震惊,继而对Java语言产生怀疑;或许在使用虚拟机遇见内存溢出等一系列异常时头疼万分,困扰于为什么会出现各种问题。

和语言朝夕相处的开发者们,提及代码的详细运行过程也难免会一时语塞。这都是由于Java虚拟机封装得太好,让使用者几乎感觉不到它的存在。虽然这种“一次编写,到处运行”优势颇多,但是却也让我们忽略了学习Java虚拟机的必要。

熟知Java虚拟机的工作原理可以大幅提升日常编程的效率,对寻常Bug的修复更是轻而易举。同时,这也是Java技术的重要组成成分之一,是实现技术进阶必不可缺的知识。

本专栏通过揭秘Java 虚拟机的工作原理,详细阐述Java程序是如何被执行并且被优化的。介绍的内容并不限于某一个版本,从8到11都会涉及。通过学习此专栏,你将了解如何编写高效的代码,如何对Bug达到最优处理,以及如何针对自己的应用调整虚拟机的运行参数。

作者简介

郑雨迪,Oracle Labs高级研究员,GraalVM编译器组核心开发者之一。研究方向包括动态编译及程序分析。在加入Oracle Labs前,郑雨迪于瑞士卢加诺大学攻读并获得计算机博士学位。

郑雨迪在Java虚拟机性能优化方向有多年研究经验,在攻读博士学位期间,郑雨迪致力于Java字节码注入、Java虚拟机监控工具方面的研究,并提出过一套针对动态编译的解决方案。这些研究工作已发表在程序语言方向的顶级会议上,得到了不少学术界及工业界同行的认可。郑雨迪在Oracle Labs主要负责研究如何通过程序分析,以及动态编译让程序语言跑得更快。工作同样是分析性能瓶颈寻找优化空间。

热点专题: 六问Java虚拟机

专栏模块

本专栏共36期,分为四大模块。

模块一 Java虚拟机基本原理

剖析Java虚拟机的运行机制,逐次介绍Java虚拟机的设计决策以及工程实现。

模块二 高效编译

在本模块中,作者将带你探索Java编译器,以及内嵌于Java虚拟机中的即时编译器,帮助你更好地理解Java语言特性,继而写出简洁高效的代码。

模块三 代码优化

在实践过程中我们经常会遇到形形色色的性能问题,解决方法不外乎加机器加内存。本模块将介绍上述方法失效后的Plan B,即如何利用工具定位并解决代码中的潜在问题,以及在已有工具不适用的情况下,如何打造专属轮子。此外,本模块还将介绍对JVM内存管理失去信心的开发者所选取的解决方案,以备不时之需。

模块四 虚拟机黑科技

当一门程序语言成熟稳定后,技术大神们便热衷于用这种语言开发实现编译器或虚拟机。在Java 10中,Graal已作为试验性即时编译器一同发布。本模块将详细科普GraalVM的各个组成部分,其中包括编译器Graal,语言实现框架Truffle,以及支持Ahead-of-Time(AOT)编译的SubstrateVM。

专栏目录

适宜人群

  1. 希望了解底层Java虚拟机实现的开发者。
  2. 有一定Java基础,希望达成技术进阶的Java工程师。
  3. 希望在面试中对答如流的Java语言应聘者,以及希望考倒应聘者的面试官们。
  4. 想要了解 Oracle GraalVM黑科技,或考虑借此技术转型的开发人员。