1. JVM內存和操作系統內存關係
操作系統內存也有堆和棧。操作系統的棧由操作系統自己管理。操作系統的堆是開放的。
JVM的內存是操作系統堆中的一塊區域。
對於操作系統來說,jvm只是一個普通的程序。
對於java程序來說,jvm是運行java程序的載體。
換言之,類加載過程,其實就是把在操作系統中編譯完成的.class文件轉換爲jvm可識別的程序的過程。
2. JVM結構圖
方法區:用於存儲虛擬機加載的:靜態變量+常量+類信息+運行時常量池;
堆:堆區主要用於存放對象實例及數組,所有new出來的對象都存儲在該區域;
虛擬機棧:虛擬機棧佔用的是操作系統內存,每個線程對應一個虛擬機棧,它是線程私有的;存放一些程序運行期間必要的東西,比如存儲局部變量表、動態鏈接、操作數和方法出口等;
本地方法棧:本地方法棧用於支持native方法的執行,存儲了每個native方法的執行狀態;
程序計數器:JVM在解釋字節碼(.class)文件時,存儲當前線程執行的字節碼行號。
3. 類加載過程
(1)將class文件字節碼內容加載到內存中,並將這些靜態數據轉換成方法區中的運行時數據結構,在堆中生成一個代表這個類的java.lang.Class對象,作爲方法區類數據的訪問入口,這個過程需要類加載器參與。
(2)分爲三個階段:
1)驗證階段:驗證文件的安全性,防止對jvm本身造成危害;
2)準備階段:正式爲類變量(static變量)分配內存並設置類變量初始值
3)解析階段:虛擬機常量池的符號引用替換爲字節引用過程
(3)執行類構造器初始化類對象;
4. 由類加載過程延伸的問題
(1)類加載器?
虛擬機提供了3種類加載器:
啓動類加載器:主要加載的是JVM自身需要的類,這個類加載使用C++語言實現的,是虛擬機自身的一部分;
擴展類加載器:負責加載JAVAHOME路徑下的jdk中的一些類庫;
系統類加載器:負責加載CLASSPATH路徑下的應用程序。
(2)jvm以什麼樣的方式加載一個類
採用的是按需加載的方式,也就是說當需要使用該類時纔會將它的class文件加載到內存生成class對象,而且加載某個類的class文件時,Java虛擬機採用的是雙親委派模式即把請求交由父類處理,它一種任務委派模式。 那麼,一起來理解下雙親委派模式:
雙親委派模式要求除了頂層的啓動類加載器外,其餘的類加載器都應當有自己的父類加載器,請注意雙親委派模式中的父子關係並非通常所說的類繼承關係,而是採用組合關係來複用父類加載器的相關代碼。
雙親委派模式的好處是避免了一個類會被重複加載。
(3)jvm什麼時候決定加載一個類?
1)創建對象就會觸發加載;
2)引用了該類的靜態屬性、方法都會觸發類的加載;
4)初始化子類也會導致父類被加載;
(4)java中創建對象的幾種方式?
1) new對象
2) 用反射創建對象
3) 克隆對象
4) 序列化
參考博客: