JVM学习笔记
概述
为什么要学习JVM
- 理解原理
- 方便调优
什么是JVM
JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。
Java语言的一个非常重要的特点就是与平台的无关性。而使用Java虚拟机是实现这一特点的关键。一般的高级语言如果要在不同的平台上运行,至少需要编译成不同的目标代码。而引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译。Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。Java虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行。这就是Java的能够“一次编译,到处运行”的原因。
作为程序员,一般的工作是编写xxx.java文件,然后通过javac把.java文件编译成.class文件,就可以运行在JVM上了。JVM在不同的操作系统都有不同的实现。
我们这里说的虚拟机是所谓的高级语言虚拟机, 并不是像Vmware那样, 完全虚拟一个硬件和操作系统出来。此外java虚拟机上还可以运行clojure, scala , Jruby, Jptyon等语言
虚拟机并不是Java的专利,Ruby、 PHP、 Python都有自己的虚拟机
为什么要用虚拟机?
- 跨平台
- CPU指令集不用
- 操作系统接口不同
- 效率更高
- 相对于解释型语言
- 抽象层次高,更容易编程
- 消除指针
- 不用管理内存
Java 程序的执行过程
源程序编译成字节码,装载(验证解析初始化)生成运行时结构(常量池代码堆函数栈),执行得出结果
从Hello World说起
Class 二进制文件一览
可以通过javap反编译查看一个class文件的详细信息
C:\Users\hasee\Desktop\jvm>javap -c -v Hello
Classfile /C:/Users/hasee/Desktop/jvm/Hello.class
Last modified 2018-3-3; size 416 bytes
MD5 checksum 144f011c8abb2ffb71cc8fb0d5f86e77
Compiled from "Hello.java"
class Hello
minor version: 0
major version: 52
flags: ACC_SUPER
Constant pool:
#1 = Methodref #6.#15 // java/lang/Object."<init>":()V
#2 = Fieldref #16.#17 // java/lang/System.out:Ljava/io/PrintStream;
#3 = String #18 // Hello World!
#4 = Methodref #19.#20 // java/io/PrintStream.println:(Ljava/lang/String;)V
#5 = Class #21 // Hello
#6 = Class #22 // java/lang/Object
#7 = Utf8 <init>
#8 = Utf8 ()V
#9 = Utf8 Code
#10 = Utf8 LineNumberTable
#11 = Utf8 main
#12 = Utf8 ([Ljava/lang/String;)V
#13 = Utf8 SourceFile
#14 = Utf8 Hello.java
#15 = NameAndType #7:#8 // "<init>":()V
#16 = Class #23 // java/lang/System
#17 = NameAndType #24:#25 // out:Ljava/io/PrintStream;
#18 = Utf8 Hello World!
#19 = Class #26 // java/io/PrintStream
#20 = NameAndType #27:#28 // println:(Ljava/lang/String;)V
#21 = Utf8 Hello
#22 = Utf8 java/lang/Object
#23 = Utf8 java/lang/System
#24 = Utf8 out
#25 = Utf8 Ljava/io/PrintStream;
#26 = Utf8 java/io/PrintStream
#27 = Utf8 println
#28 = Utf8 (Ljava/lang/String;)V
{
Hello();
descriptor: ()V
flags:
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 1: 0
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=1, args_size=1
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String Hello World!
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
LineNumberTable:
line 5: 0
line 6: 8
}
SourceFile: "Hello.java"
具体的指令,比如aload_0、invokespecial、return、getstatic、ldc、invokevirtual等,我们以后再详细介绍含义。
使用开源软件classpy可以直观的理解java类文件结构,如图1、2所示。通过左侧的树状列表,我们可以观察Hello.class的基本结构,如果像常量池这种复杂的结构,可以点开看具体结构,至于每个结构占多少字节我们以后再详细了解。