在上篇文章我们聊到,无论什么语言写的代码,其到最后都是通过机器码运行的,无一例外.那么对于 Java 语言来说,其从源代码到机器码,这中间到底发生了什么呢?这就是今天我们要聊的. 如下图所示,编译器可以分为:前端编译器.JIT 编译器和AOT编译器.下面我们逐个讲解. 前端编译器:源代码到字节码 之前我们说到:对于 Java 虚拟机来说,其实际输入的是字节码文件,而不是 Java 文件.那么对于 Java 语言而言,其实怎么将 Java 代码转化成字节码文件的呢?我们知道在 JDK 的安装目录里…
查看虚拟机进程:jps 命令 jps 命令可以列出所有的 Java 进程.如果 jps 不加任何参数,可以列出 Java 程序的进程 ID 以及 Main 函数短名称,如下所示. $ jps 6540 Jps 64447 Main 除此之外,还可以指定下面的参数自定义输出信息: 参数 含义 -q 指定jps只输出进程ID -m 输出传递给Java进程的参数 -l 输出主函数的完整路径 -v 显示传递给Java虚拟机的参数 虚拟机统计信息:jstat 命令 jstat 用于观察 Java 堆信息的…
说到 Java 虚拟机,不得不提的就是 Java 虚拟机的 GC(Garbage Collection)日志.而对于 GC 日志,我们不仅要学会看懂,而且要学会如何设置对应的 GC 日志参数.今天就让我们来学习一下 Java 虚拟机中所有与 GC 日志有关的参数.相信掌握了这些参数之后,对于大家线上打印 GC 日志是有不少帮助的. 为了能够更直观地显示出每个参数的作用,我们将以下面的 Demo 为例子去设置 GC 日志参数. /** * @author 陈树义 * @date 2018.09.2…
我们都知道 JVM 在启动的时候会去加载类信息,那么我们怎么得知他加载了哪些类,又卸载了哪些类呢?我们这一节就来介绍四个 JVM 参数,使用它们我们就可以清晰地知道 JVM 的类加载信息. 为了方便演示,我们使用下面的程序作为本次的演示程序. /** * @author chenshuyi * @date 2018.09.30 */ public class ClassLoadDemo { public static void main(String[] args) { String name…
JVM 中最重要的一部分就是堆空间了,基本上大多数的线上 JVM 问题都是因为堆空间造成的 OutOfMemoryError.因此掌握 JVM 关于堆空间的参数配置对于排查线上问题非常重要. tips:本文所有配置,如无特别说明,均基于JDK1.8. 堆配置 我们使用 -Xms 设置堆的初始空间大小,使用 -Xmx 设置堆的最大空间大小. java -Xms20m -Xmx30m GCDemo 在上面的命令中,我们设置 JVM 的初始堆大小为 20M,最大堆空间为 30M. 年轻代 在 JDK1…
我们经常会听到许多垃圾回收的术语,例如:Minor GC.Major GC.Young GC.Old GC.Full GC.Stop-The-World 等.但这些 GC 术语到底指的是什么,它们之间的区别到底是什么?今天我们就来详细说说. Minor GC 从年轻代空间回收内存被称为 Minor GC,有时候也称之为 Young GC.对于 Minor GC,你需要知道的一些点: 当 JVM 无法为一个新的对象分配空间时会触发 Minor GC,比如当 Eden 区满了.所以 Eden 区越小…
前面文章中,我们介绍了 Java 虚拟机的内存结构,Java 虚拟机的垃圾回收机制,那么这篇文章我们说说具体执行垃圾回收的垃圾回收器. 总的来说,Java 虚拟机的垃圾回收器可以分为四大类别:串行回收器.并行回收器.CMS 回收器.G1 回收器. 串行回收器 串行回收器是指使用单线程进行垃圾回收的回收器.因为每次回收时只有一个线程,因此串行回收器在并发能力较弱的计算机上,其专注性和独占性的特点往往能让其有更好的性能表现. 串行回收器可以在新生代和老年代使用,根据作用于不同的堆空间,分为新生代串行…
在第 6 讲中我们说到 Java 虚拟机的内存结构,提到了这部分的规范其实是由<Java 虚拟机规范>指定的,每个 Java 虚拟机可能都有不同的实现.其实涉及到 Java 虚拟机的内存,就不得不谈到 Java 虚拟机的垃圾回收机制.因为内存总是有限的,我们需要一个机制来不断地回收废弃的内存,从而实现内存的循环利用,这样程序才能正常地运转下去. 比起 Java 虚拟机的内存结构有<Java 虚拟机规范>规定,垃圾回收机制并没有具体的规范约束.所以很多时候不同的虚拟机有不同的实现方式…
当 Java 虚拟机将 Java 源码编译为字节码之后,虚拟机便可以将字节码读取进内存,从而进行解析.运行等整个过程,这个过程我们叫:Java 虚拟机的类加载机制.JVM 虚拟机执行 class 字节码的过程可以分为七个阶段:加载.验证.准备.解析.初始化.使用.卸载. 在开始聊之前,先给大家看一道面试题. class Grandpa { static { System.out.println("爷爷在静态代码块"); } } class Father extends Grandpa…
看到这里,我相信大家对于一个 Java 源文件是如何变成字节码文件,以及字节码文件的含义已经非常清楚了.那么接下来就是让 Java 虚拟机运行字节码文件,从而得出我们最终想要的结果了.在这个过程中,Java 虚拟机会加载字节码文件,将其存入 Java 虚拟机的内存空间中,之后进行一系列的初始化动作,最后运行程序得出结果. 那么字节码数据在 Java 虚拟机内存中是如何存放的 ?Java 虚拟机在为类实例或成员变量分配内存是如何分配的 ?要解答上面这些问题,我们首先需要了解一下 Java 虚拟机的…