學(xué)習(xí)Java不可避免的要學(xué)習(xí)Java虛擬機(jī),,也就是JVM,,Java虛擬機(jī)規(guī)范里面規(guī)定了程序運行期間會使用到的運行時數(shù)據(jù)區(qū),這也是JVM的內(nèi)存區(qū)域劃分的模型,,應(yīng)該可以這么理解吧,。 這其中有一些是隨著虛擬機(jī)的啟動和退出而創(chuàng)建和銷毀的,這些區(qū)域是線程共享的,,另外有一些是跟各個線程綁定的,,隨著線程的開始和結(jié)束而創(chuàng)建和銷毀,我們可以稱這些區(qū)域是線程私有的,。 根據(jù)《Java虛擬機(jī)規(guī)范Java SE 7版》和《Java虛擬機(jī)規(guī)范Java SE 8版》的規(guī)定,,我們可以劃分出如下幾個運行時數(shù)據(jù)區(qū),如下圖所示:Java堆在Java虛擬機(jī)中,,堆是可供各個線程共享的運行時內(nèi)存區(qū)域,,也是供所有類實例和數(shù)組對象分配內(nèi)存的區(qū)域。這塊區(qū)域隨著虛擬機(jī)的啟動而創(chuàng)建,,它的唯一使命就是存放對象實例,,這塊區(qū)域也是GC主要關(guān)注的地方。 下面的就是我的筆記本上的JVM堆的劃分情況,,可以看到分為新生代,、老年代和永久代,新生代里面有可以分為Eden Space,、From Survivor Space和To Survivor Space,。 Heap Usage: PS Young Generation Eden Space: capacity = 17301504 (16.5MB) used = 2483088 (2.3680572509765625MB) free = 14818416 (14.131942749023438MB) 14.351862127130682% used From Space: capacity = 2621440 (2.5MB) used = 2615312 (2.4941558837890625MB) free = 6128 (0.0058441162109375MB) 99.7662353515625% used To Space: capacity = 6291456 (6.0MB) used = 0 (0.0MB) free = 6291456 (6.0MB) 0.0% used PS Old Generation capacity = 44564480 (42.5MB) used = 13316368 (12.699478149414062MB) free = 31248112 (29.800521850585938MB) 29.88112505744485% used PS Perm Generation capacity = 22020096 (21.0MB) used = 14907008 (14.2164306640625MB) free = 7113088 (6.7835693359375MB) 67.6972888764881% used 根據(jù)虛擬機(jī)規(guī)范的規(guī)定,Java堆可以是固定的大小也可以是按照需求動態(tài)擴(kuò)展的,,而且不需要保證是連續(xù)的,。 存放內(nèi)容:所有的對象實例和數(shù)組,。 方法區(qū)方法區(qū)是一個線程共享的區(qū)域,它用于存儲已被虛擬機(jī)加載的類信息,、常量,、靜態(tài)變量。方法區(qū)是堆的邏輯組成部分,,Hotspot用永久代實現(xiàn)了方法區(qū),。 方法區(qū)還包含運行時常量池,用于存放編譯時生成的各種字面量和符號引用,,但是不要求常量一定是在編譯時期產(chǎn)生的,,運行期間也可以將新的常量放入池中,比如String的intern方法便是利用了這一特性,。存放內(nèi)容:類的結(jié)構(gòu)信息,,如類的字段、方法,、接口,、構(gòu)造函數(shù),還有運行時常量池等,。 程序計數(shù)寄存器這塊區(qū)域是每個線程獨立擁有的,,也就是線程私有的,我們可以把它看作是當(dāng)前線程所執(zhí)行的字節(jié)碼的行號指示器,。 這塊區(qū)域時虛擬機(jī)規(guī)范里面唯一一個沒有規(guī)定任何OutOfMemoryError情況的區(qū)域。 存放內(nèi)容:如果線程執(zhí)行的是一個Java方法,,那么寄存器里面記錄的就是正在執(zhí)行的虛擬機(jī)字節(jié)碼指令的地址,,如果線程執(zhí)行的是一個native方法,那么寄存器記錄的值為undefined,。 虛擬機(jī)棧虛擬機(jī)棧也是線程私有的內(nèi)存區(qū)域,。每個方法在執(zhí)行的時候都會創(chuàng)建一個棧幀用于存儲局部變量表、操作數(shù)棧,、方法出口等信息,,每一個方法從調(diào)用到執(zhí)行完成就是一個棧幀入棧和出棧的過程。 局部變量表存放了編譯時期可知的各種基本數(shù)據(jù)類型,、對象引用和指向了一條字節(jié)碼指令的地址,。 存放內(nèi)容:局部變量表、操作數(shù)棧,、方法出口等信息,。 本地方法棧 |
|