前言
在前面的文章我们讲过JVM的内存结构,虚拟机栈和Java堆,这章我们通过字节码指令来观察两者的差异。
一、准备工作
代码如下:
public class Main {
int count = 0;
public static void test1() {
}
public void test2() {
int i = 0;
int j;
j = i++;
}
public void test3() {
int i = 0;
int j;
j = ++i;
}
public void test4() {
for (int i = 0; i < 10; i++) {
}
}
public void test5() {
for (int i = 0; i < 10; ++i) {
}
}
public void test6() {
count++;
}
}
为什么要写一个空的static方法呢,下面会讲解。
用javap指令对class文件生成字节码指令。
我们可以看到字节码指令如下。
Classfile /G:/Hello/out/production/Hello/Main.class
Last modified 2019-2-2; size 842 bytes
MD5 checksum 738e1e17511038bde0edaa8373957a6c
Compiled from "Main.java"
public class Main
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #4.#25 // java/lang/Object."<init>":()V
#2 = Fieldref #3.#26 // Main.count:I
#3 = Class #27 // Main
#4 = Class #28 // java/lang/Object
#5 = Utf8 count
#6 = Utf8 I
#7 = Utf8 <init>
#8 = Utf8 ()V
#9 = Utf8 Code
#10 = Utf8 LineNumberTable
#11 = Utf8 LocalVariableTable
#12 = Utf8 this
#13 = Utf8 LMain;
#14 = Utf8 test1
#15 = Utf8 test2
#16 = Utf8 i
#17 = Utf8 j
#18 = Utf8 test3
#19 = Utf8 test4
#20 = Utf8 StackMapTable
#21 = Utf8 test5
#22 = Utf8 test6
#23 = Utf8 SourceFile
#24 = Utf8 Main.java
#25 = NameAndType #7:#8 // "<init>":()V
#26 = NameAndType #5:#6 // count:I
#27 = Utf8 Main
#28 = Utf8 java/lang/Object
{
int count;
descriptor: I
flags:
public Main();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=2, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: iconst_0
6: putfield #2 // Field count:I
9: return
LineNumberTable:
line 1: 0
line 2: 4
LocalVariableTable:
Start Length Slot Name Signature
0 10 0 this LMain;
publi