- 前言
- JVM是啥?
- class file format 解读
- 1 = Methodref #3.#13 // java/lang/Object.”
“:()V - 2 = Class #14 // com/example/demo/jvm/EmptyClass
- 3 = Class #15 // java/lang/Object
- 4 = Utf8
- 5 = Utf8 ()V
- 6 = Utf8 Code
- 7 = Utf8 LineNumberTable
- 8 = Utf8 LocalVariableTable
- 9 = Utf8 this
- 10 = Utf8 Lcom/example/demo/jvm/EmptyClass;
- 11 = Utf8 SourceFile
- 12 = Utf8 EmptyClass.java
- 13 = NameAndType #4:#5 // “
“:()V - 14 = Utf8 com/example/demo/jvm/EmptyClass
- 15 = Utf8 java/lang/Object
前言
为啥要学习JVM?
- 为了更好的掌握高并发编程.想要成为一个合格的高级开发或者架构师,为了应对大量请求,多线程高并发开发是必须掌握的东西.而java的多线程跟JVM有着密切的关系,为了更好的理解掌握高并发开发,必须掌握JVM知识.
- 为了JVM调优,GC等.不同的项目场景,对象的生命周期也不同,这就要尝试去合理分配JVM的各个内存区域的大小,以提高性能.
也可以通过JVM去了解JAVA的一些关键字(例如synchronized)的实现原理,出现问题后也好排查
JVM是啥?
定义:
JVM是一种规范,Java virtual machine specifications.
JVM的实现(比如HotSpot)可以理解为虚拟出来的一台计算机,有自己的字节码指令集(汇编语言)和内存管理(栈,堆,方法区等)
JDK Documentation
JVM specs11
JRE = JVM + core lib
JDK = JRE + development kit(一些调试工具)
下面这张图,也有的说法讲classLoader不属于JVM,概念无所谓,领会精神即可.
有很多语言可以运行在JVM上
JVM其实和java是独立的,JVM值需要class格式的文件(或文件流)
任何语言-编译或动态生成->.class文件-运行在->JVM
常见的JVM的实现
java -version就可以看到自己用的JVM的详情
HotSpot:oracle官方的实现(最早是sun,后来被Oracle收购)
- Jrockit:BEA,曾号称世界最快JVM,被Oracle收购合并于HotSpot
- J9:IBM的实现
- Microsoft VM
- Alibaba Dragonwell:HotSpot深度定制版
- LiquidVM:直接针对硬件
- azul zing:垃圾回收牛批(最新业界标杆),据说很贵
Class file format
class文件是一个二进制的字节流;
class文件的格式设计的特别牛批,很紧密,没有任何分隔符,得到了很多大牛的认可,所以他们设计语言时会选择翻译成class运行在JVM上
我感觉这部分比较繁琐枯燥且平时用不到 ,很多东西先了解/记录一下,以后用得着的时候再更一步了解.
需配合官网JVM规范第七节(java的汇编语言)一起食用.
简单认识下编译后的class文件
写个空类,里面啥都没有,用JDK1.8编译,我们看看它的class文件是啥样的:
EmptyClass.java:
public class EmptyClass {}
对应的class文件其实是个二进制文件,
IDEA里面查看会自动帮我们反编译
可以看到,多了个无参构造方法:
public class EmptyClass { public EmptyClass() { }}
按16进制格式打开(hexadecimal)
IntelliJ IDEA可以安装一个BinEd的插件打开;
如果用SublimeText打开的话,它是以16进制打开的:
cafe babe 0000 0034 0010 0a00 0300 0d07
000e 0700 0f01 0006 3c69 6e69 743e 0100
0328 2956 0100 0443 6f64 6501 000f 4c69
6e65 4e75 6d62 6572 5461 626c 6501 0012
4c6f 6361 6c56 6172 6961 626c 6554 6162
6c65 0100 0474 6869 7301 0021 4c63 6f6d
2f65 7861 6d70 6c65 2f64 656d 6f2f 6a76
6d2f 456d 7074 7943 6c61 7373 3b01 000a
536f 7572 6365 4669 6c65 0100 0f45 6d70
7479 436c 6173 732e 6a61 7661 0c00 0400
0501 001f 636f 6d2f 6578 616d 706c 652f
6465 6d6f 2f6a 766d 2f45 6d70 7479 436c
6173 7301 0010 6a61 7661 2f6c 616e 672f
4f62 6a65 6374 0021 0002 0003 0000 0000
0001 0001 0004 0005 0001 0006 0000 002f
0001 0001 0000 0005 2ab7 0001 b100 0000
0200 0700 0000 0600 0100 0000 0700 0800
0000 0c00 0100 0000 0500 0900 0a00 0000
0100 0b00 0000 0200 0c
class file format 解读
从前到后的依次是: Magic Number, Minor version, Major version,等等,具体见下面class file规范
每个16进制的数字占4位,1个字节是8位,所以下面一个方格代表一个字节.
java的class文件的Magic Number一般都是 cafe babe
class文件版本号version,JDK7默认是51.0,JDK8默认是52.0,依次递增;51 52都是Major Version, 后面的小数位是Minor Version
有时候我们用JDK8编译的项目在JDK7的环境上跑时,会抛异常:xxxx version 52.0
后面是constant_pool_count
在后面是constant_pool_count-1个constant_pool,从#1开始,因为#0做了个预留-代表没有任何引用指向它.
显示class信息的工具
- javap
javap -v EmptyClass.class 输出: ```java Classfile /Users/liweizhi/IdeaProjects/msb-class/demo/target/classes/com/example/demo/jvm/EmptyClass.class Last modified 2020-3-23; size 297 bytes MD5 checksum a2e3e21cc6e7c6b5d8035663b369a23c Compiled from “EmptyClass.java” public class com.example.demo.jvm.EmptyClass minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPER Constant pool:1 = Methodref #3.#13 // java/lang/Object.”
“:()V 2 = Class #14 // com/example/demo/jvm/EmptyClass
3 = Class #15 // java/lang/Object
4 = Utf8
5 = Utf8 ()V
6 = Utf8 Code
7 = Utf8 LineNumberTable
8 = Utf8 LocalVariableTable
9 = Utf8 this
10 = Utf8 Lcom/example/demo/jvm/EmptyClass;
11 = Utf8 SourceFile
12 = Utf8 EmptyClass.java
13 = NameAndType #4:#5 // “
“:()V 14 = Utf8 com/example/demo/jvm/EmptyClass
15 = Utf8 java/lang/Object
{ public com.example.demo.jvm.EmptyClass(); descriptor: ()V flags: ACC_PUBLIC Code:
} SourceFile: “EmptyClass.java”stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 7: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcom/example/demo/jvm/EmptyClass;
```
- JBE,可以查看并修改
- JClassLib bytecode viewer,IDEA的插件,便捷好用✅
- 安装插件
- 光标点击进入Java文件
- view -> Show Bytecode With jclassLib