JVM就是java虛擬機,JVM 內存共分爲虛擬機棧、堆、方法區、程序計數器、本地方法棧五個部分。
1.類的加載(加載到JVM)
class文件通過類加載器加載到內存。
類加載全過程:加載Class對象---連接(1.驗證(安全和規範),2.準備(分配內存),3.解析(將類中的符號引用轉換成直接引用))---初始化---使用---卸載
類加載器使用的加載模式:雙親委託機制
- 1、當AppClassLoader加載一個class時,它首先不會自己去嘗試加載這個類,而是把類加載請求委派給父類加載器ExtClassLoader去完成。
- 2、當ExtClassLoader加載一個class時,它首先也不會自己去嘗試加載這個類,而是把類加載請求委派給BootStrapClassLoader去完成。
- 3、如果BootStrapClassLoader加載失敗(例如在$JAVA_HOME/jre/lib裏未查找到該class),會使用ExtClassLoader來嘗試加載;
- 4、若ExtClassLoader也加載失敗,則會使用AppClassLoader來加載
- 5、如果AppClassLoader也加載失敗,則會報出異常ClassNotFoundException
類加載器:
BootStrapClassLoader 啓動類加載器 負責jre/lib/rt.jar
ExtClassLoader 擴展類加載器 jre/lib/*.jar或-Djava.ext.dirs
AppClassLoader 應用類加載器 記載classpath中指定的jar包及目錄中class
UserClassLoader 自定義的類加載器 繼承ClassLoader getClass().ClassLoader()可以獲得
2.在類加載檢查通過後,接下來虛擬機將爲新生對象分配內存。
別人家畫內存模型, 戳這裏 http://www.cnblogs.com/lfs2640666960/p/9297176.html
簡單看了一下內存模型,簡單看看每個區域究竟存儲的是什麼(乾的是什麼):
- 堆:存放對象實例,幾乎所有的對象實例都在這裏分配內存
- 虛擬機棧:虛擬機棧描述的是Java方法執行的內存模型:每個方法被執行的時候都會同時創建一個棧幀(Stack Frame)用於存儲局部變量表、操作棧、動態鏈接、方法出口等信息
- 本地方法棧:本地方法棧則是爲虛擬機使用到的Native方法服務。
- 方法區:存儲已被虛擬機加載的類元數據信息(元空間)
- 程序計數器:當前線程所執行的字節碼的行號指示器
我來宏觀簡述一下工作流程:
- 1、通過
java.exe
運行Java3yTest.class
,隨後被加載到JVM中,方法區(元空間)存儲着類的信息(包括類的名稱、方法信息、字段信息..)。 - 2、然後JVM找到Java3yTest的主函數入口(main),爲main函數創建棧幀,開始執行main函數
- 3、main函數的第一條命令是
Java3y java3y = new Java3y();
就是讓JVM創建一個Java3y對象,但是這時候方法區中沒有Java3y類的信息,所以JVM馬上加載Java3y類,把Java3y類的類型信息放到方法區中(元空間) - 4、加載完Java3y類之後,Java虛擬機做的第一件事情就是在堆區中爲一個新的Java3y實例分配內存, 然後調用構造函數初始化Java3y實例,這個Java3y實例持有着指向方法區的Java3y類的類型信息(其中包含有方法表,java動態綁定的底層實現)的引用
- 5、當使用
java3y.setName("Java3y");
的時候,JVM根據java3y引用找到Java3y對象,然後根據Java3y對象持有的引用定位到方法區中Java3y類的類型信息的方法表,獲得setName()
函數的字節碼的地址 - 6、爲
setName()
函數創建棧幀,開始運行setName()
函數。
3.GC