JVM內存結構小記
JVM內存結構主要包括兩個子系統和兩個組件。兩個子系統分別是Classloader子系統和Executionengine(執行引擎)子系統;兩個組件分別是Runtimedataarea(運行時數據區域)組件和Nativeinterface(本地接口)組件。
Classloader子系統:裝載class信息到運行時數據區
Executionengine(執行引擎)子系統:執行Class的地方
Runtimedataarea(運行時數據區域)組件:經常說的JVM內存,分為5個區域
(1)heap(堆):存放new 出來的對象和數組,由GC管理內存,每個JVM實例一個堆
(2)javastack(棧):每個線程一個javastack,只有壓棧和出棧2個動作,以楨為單位
(3)methodarea(方法區):每個JVM實例一個,存儲類信息,靜態的變量
(4)ProgramCounter:每個線程都有一個PC寄存器,記錄線程執行的下個地址
(5)nativemethodstack:保存本地方法進去區域的地址
這里heap和methodarea是所有線程共享,而其他3個則是以線程為粒度隔離的。
Nativeinterface(本地接口)組件:與本地lib交互,是與其他語言交互的接口,當調用native方法時,不受JVM限制,可能會拋nativeheapOutOfMemory
棧是JVM的內存指令區,JAVA基本類型,JAVA指令代碼,常量都保存在stack中,存取速度快,數據可以共享,缺點是棧中的數據大小和生命周期是確定的,不靈活
堆是JVM的內存數據區,對象實例包括他的屬性都作為數據存儲在heap中,對象實例在heap中分配好后,需要在stack中保存4個字節的heap內存地址,用來定位該對象在heap的位置,找到該實例,可以動態的分配內存大小,生存期不需要告訴編譯器,但是存取慢。
例子:對象的方法和屬性保存在哪里?
方法信息在方法區中,屬性在heap中
另外,對象的靜態屬性在方法區中。
非靜態方法和靜態方法:
實例方法有一個隱含的傳入參數,該參數就是this,也就是當前對象實例在stack中的地址指針,因為調用非靜態方法時,都要先new出來。
靜態方法無此隱含參數,不需要new 對象,只要class文件被ClassLoader加載到JVM的stack中,靜態方法就能被調用,當然,靜態方法取不到heap中的對象屬性,因為還沒對象呢。。。