用下面的代码来说明JVM的执行过程
public class HelloWorld {
private Object object=new Object();
private static int i=0;
private static String s="HelloWorld";
public int add(){
int a=1;
int b=2;
int c=(a+b)*100;
return c;
}
public static void main(String[] args) {
HelloWorld app=new HelloWorld();
int result=app.add();
System.out.println("result = [" + result + "]");
}
}
通过javap -c 来反编译class文件,能得到下面的执行过程
PS C:> javap -c HelloWorld.class
Compiled from "HelloWorld.java"
public class com.ichangtou.api.login.controller.HelloWorld {
public com.ichangtou.api.login.controller.HelloWorld();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: new #2 // class java/lang/Object
8: dup
9: invokespecial #1 // Method java/lang/Object."<init>":()V
12: putfield #3 // Field object:Ljava/lang/Object;
15: return
public int add();
Code:
0: iconst_1
1: istore_1
2: iconst_2
3: istore_2
4: iload_1
5: iload_2
6: iadd
7: bipush 100
9: imul
10: istore_3
11: iload_3
12: ireturn
public static void main(java.lang.String[]);
Code:
0: new #4 // class com/ichangtou/api/login/controller/HelloWorld
3: dup
4: invokespecial #5 // Method "<init>":()V
7: astore_1
8: aload_1
9: invokevirtual #6 // Method add:()I
12: istore_2
13: getstatic #7 // Field java/lang/System.out:Ljava/io/PrintStream;
16: new #8 // class java/lang/StringBuilder
19: dup
20: invokespecial #9 // Method java/lang/StringBuilder."<init>":()V
23: ldc #10 // String result = [
25: invokevirtual #11 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
28: iload_2
29: invokevirtual #12 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
32: ldc #13 // String ]
34: invokevirtual #11 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
37: invokevirtual #14 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
40: invokevirtual #15 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
43: return
static {};
Code:
0: iconst_0
1: putstatic #16 // Field i:I
4: ldc #17 // String HelloWorld
6: putstatic #18 // Field s:Ljava/lang/String;
9: return
}
首先虚拟机栈是先进后出,从main方法压栈,然后add方法。由入口进入后,执行add方法,iconst_1代表将int类型常量1放入操作数栈中,istore_1是将1存入局部变量中,也就是给a赋值,b=2同理,iload_1会把a=1的值,也就是1压到操作数栈中,2也会压操作数栈中,iadd的意思是把1和2进行相加。然后将100压入操作数栈,imul的意思是3乘以100,istore_3是把300存入局部变量C中,iload_3取出300,压入操作数栈中,ireturn 意思是从方法中返回int类型的数据,然后300通过方法出口,就对应上了main方法的局部变量result上。
通过以下的代码,结合VisualVM插件,就能很直观的看到堆中的变化
import java.util.ArrayList;
import java.util.List;
public class heapOon {
byte[] b = new byte[1024 * 10];
public static void main(String[] args)throws InterruptedException {
List<heapOon> all = new ArrayList<heapOon>();
while (true) {
all.add(new heapOon());
Thread.sleep(10);
}
}
}
在idea中安装VisualVM插件
启动项目后,在工具-可用插件中找到Visual GC
这里可以明显的看到Eden换慢慢的增长,说明有对象不断的生成,然后经过一次回收,会转移到S0,然后到S1,然后到Old(老年代)
当old满了的时候,就会出现内存异常,程序也就会停止