JVM總體架構以下:java
經過編寫代碼來分析整個內存區域架構
public class Math { public static final Integer CONSTANT = 666; public int compute(){ int a = 1; int b = 2; int c = (a + b) * 10; return c; } public static void main(String[] args) { Math math = new Math(); math.compute(); } }
對上述代碼的class文件進行javap - c Math.class > Math.txt
jvm
javap -c
是對代碼進行反彙編函數
獲得Math.txt
文件命令行
對compute方法進行分析:code
public int compute(); Code: 0: iconst_1 // 將int型(1)推送至棧頂 1: istore_1 // 將棧頂int型數值存入第二個本地變量 2: iconst_2 // 將int型(2)推送至棧頂 3: istore_2 // 將棧頂int型數值存入第三個本地變量 4: iload_1 // 將第二個int型本地變量推送至棧頂 5: iload_2 // 將第三個int型本地變量推送至棧頂 6: iadd // 將棧頂兩int型數值相加並將結果壓入棧頂 7: bipush 10 // 將單字節的常量值(-128~127)推送至棧頂 9: imul // 將棧頂兩int型數值相乘並將結果壓入棧頂 10: istore_3 // 將棧頂int型數值存入第四個本地變量 11: iload_3 // 將第四個int型本地變量推送至棧頂 12: ireturn
上面程序,在JVM中的運行時區域以下:對象
操做的操做暫時的數據存放到操做數棧
。blog
main()的局部變量表存放對象的引用地址。ip
動態連接
就是當咱們這個程序運行main方法時,當執行math對象額compute方法時,去compute方法執行,compute方法算是符號引用,找到符號引用所在的方法體,執行。內存
執行javap -v Math.class > Math.txt
獲得字節碼文件
找到main方法所在的位置
public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=2, args_size=1 0: new #2 // class com/tugohost/jvm/Math 3: dup 4: invokespecial #3 // Method "<init>":()V 7: astore_1 8: aload_1 9: invokevirtual #4 // Method compute:()I 12: pop 13: return LineNumberTable: line 17: 0 line 18: 8 line 19: 13 LocalVariableTable: Start Length Slot Name Signature 0 14 0 args [Ljava/lang/String; 8 6 1 math Lcom/tugohost/jvm/Math;
其中
9: invokevirtual #4 // Method compute:()I
這一行表示,main函數中的math對象調用compute方法,
再往上找,找到常量池
找到
#4 = Methodref #2.#33 // com/tugohost/jvm/Math.compute:()I
再找#2
、#33
#2 = Class #32 // com/tugohost/jvm/Math
#3 = Methodref #2.#31 // com/tugohost/jvm/Math."":()V
因此這個過程就是動態連接
的過程。
本地方法棧就是存儲native
方法
若是Eden區放滿,會minor GC
,若是還存活的對象,會放到From區
生命值+1,同理會放到To區
生命值+1,若是生命值大於某個值(能夠本身設置),會放到老年代
。
經過寫一個死循環代碼來看看堆中垃圾收集器的工做:
public class HeapTest { byte[] a = new byte[1024 * 100]; // 100Kb public static void main(String[] args) throws InterruptedException { ArrayList<HeapTest> heapTests = new ArrayList<>(); while (true){ heapTests.add(new HeapTest()); Thread.sleep(10); } } }
經過命令行jvisualvm
打開Java visualVM
若是老年代滿了觸發Full GC
。若是Full GC
對老年代沒有用,即老年代中沒有無用的對象時,出現OOM效果。