Jvm虛擬機在執(zhí)行Java程序的過程中會把它所管理的內(nèi)存劃分為若干個不同的數(shù)據(jù)區(qū)域,。這些區(qū)域都有各自的用途,以及創(chuàng)建和銷毀的時間,,Jvm所管理的內(nèi)存將會包含以下幾個運行時數(shù)據(jù)區(qū)域,,如下圖所示。 1.程序計數(shù)器 程序計算器是一塊較小的內(nèi)存空間,,它的作用可以看做是當前線程所執(zhí)行的字節(jié)碼的行號指示器,。字節(jié)碼解釋器工作時就是通過改變這個計數(shù)器的值來選取下一條所需要執(zhí)行的字節(jié)指令,分支,、循環(huán),、跳轉(zhuǎn)、異常處理,、線程恢復等基礎功能都需要依賴這個計數(shù)器來完成,。 本文來自http://www./ 由于jvm的多線程是通過線程輪流切換并通過分配處理器執(zhí)行時間的方式來實現(xiàn)的,在任何一個確定的時刻,,一個處理器只會執(zhí)行一條線程中的指令,。因此,為了線程切換后能恢復到正確的位置,,每條線程都需要有一個獨立的線程計數(shù)器,,各線程間的計數(shù)器互不影響,獨立存儲,,我們稱這類內(nèi)存區(qū)域為”線程私有“的內(nèi)存,。
如果線程正在執(zhí)行的是一個java方法,這個計數(shù)器記錄的是正在執(zhí)行的JVM字節(jié)碼指令的地址,;如果正在執(zhí)行的是一個Native方法,,這個計數(shù)器值為空。
2.虛擬機棧
與程序計數(shù)器一樣,,虛擬機棧也是線程私有的,,它的生命周期與線程相同。虛擬機棧描述的是Java方法執(zhí)行的內(nèi)存模型:每個方法被執(zhí)行的時候都會同時創(chuàng)建一個棧幀用于存儲局部變量表,、操作棧,、動態(tài)鏈接,、方法出口等信息。每一個方法被調(diào)用直到執(zhí)行完成的過程,,就對應著一個棧幀在虛擬機中從入棧到出棧的過程,。 http://www. 局部變量表存放了編譯期可知的各種基本數(shù)據(jù)類型(boolean、byte,、char,、short、int,、float,、long、double),、對象引用和returnAddress類型(指向了一條字節(jié)碼指令的地址),。
3.本地方法棧 內(nèi)容來源http://www./ 本地方法棧與虛擬機棧所發(fā)揮的作用是非常相似的,其區(qū)別在于虛擬機棧為虛擬機執(zhí)行Java方法服務,,而本地方方法棧是為虛擬機使用到的Native方法服務,。
4.堆
對大多數(shù)應用來說,堆是虛擬機所管理的內(nèi)存中最大的一塊,。堆是被所以線程共享的一塊區(qū)域,在虛擬機啟動時創(chuàng)建,。此內(nèi)存區(qū)域的唯一目的就是存放對象實例,,幾乎所以的對象實例都在這里分配內(nèi)存。堆同時也是垃圾收集器管理的主要區(qū)域,。
5.方法區(qū)
方法區(qū)與堆一樣,,是各個線程共享的內(nèi)存區(qū)域,它用于存儲已被虛擬機加載的類信息,、常量,、靜態(tài)變量、即時編譯器編譯后的代碼等數(shù)據(jù),。對HotSpot虛擬機來說,,”永久代“也被劃分到這個區(qū)域。一般來說這個區(qū)域的內(nèi)存回收目標是針對常量池的回收和對類型的卸載,。 本文來自http://www./ 6.運行時常量池
運行時常量池是方法區(qū)的一部分,。Class文件中除了有類的版本、字段,、方法,、接口等描述信息外,還有一項信息是常量池,,用于存放編譯器生成的各種字面量和符號引用,,這部分內(nèi)容將在類加載后存放到方法區(qū)的運行時常量池中,。
7.直接內(nèi)存
直接內(nèi)存并不是虛擬機運行時數(shù)據(jù)區(qū)的一部分,但這部分內(nèi)存也被頻繁的使用,,而且也可能導致OutOfMemoryError異常出現(xiàn),。
在JDK1.4中新加入了NIO類,引入了一種基于通道與緩沖區(qū)的I/O方式,,它可以使用Native函數(shù)直接分配堆外內(nèi)存,,然后通過一個存儲在Java堆里面的DirectByteBuffer對象作為這塊內(nèi)存的引用進行操作。這樣能在一些場景中顯著提高性能,,因為避免了在Java堆和Native堆中來回復制數(shù)據(jù),。
對象訪問 內(nèi)容來源http://www./ 在Java語言中,對象的訪問時如何進行的,?即使最普通的對象訪問也會涉及到Java堆,、Java棧、方法區(qū)這三個最重要內(nèi)存區(qū)域,,如下面這段代碼: IT博客吧-做最棒的IT技術(shù)博客分享社區(qū) Object obj = new Object(),; 假設這句代碼出現(xiàn)在方法體重,那“Object obj”這部分的語義將會反映到Java棧的本地變量表中,,作為一個reference類型出現(xiàn),。而“new Object()”這部分語義將會反映到Java堆中,形成一塊存儲了Object類型所有實例數(shù)據(jù)的結(jié)構(gòu)化內(nèi)存,。在Java堆中還必須包含能查找到此對象類型數(shù)據(jù)(如對象類型,,父類,實現(xiàn)的接口,,方法等)的地址信息,,這些類型數(shù)據(jù)則存儲在方法區(qū)中。
參考《深入理解Java虛擬機》 |
|