堆
Java程序在運(yùn)行時(shí)創(chuàng)建的所有類實(shí)例或數(shù)組都放在同一個(gè)堆中。而一個(gè)Java虛擬機(jī)實(shí)例中只有一個(gè)堆空間,因此所有線程都將共享這個(gè)堆。由于一個(gè)Java程序獨(dú)占一個(gè)Java虛擬機(jī)實(shí)例,因而每個(gè)Java程序都有自己的堆空間。
Java虛擬機(jī)有一條在堆中分配新對(duì)象的指令,卻沒有釋放內(nèi)存的指令,正如你無法用Java代碼去明確釋放一個(gè)對(duì)象一樣,字節(jié)碼指令也沒有對(duì)應(yīng)的功能。虛擬機(jī)自己負(fù)責(zé)決定如何已經(jīng)合適釋放不在被運(yùn)行的程序引用的對(duì)象所占據(jù)的內(nèi)存。程序本身不用去考慮何時(shí)需要回收對(duì)象所占用的內(nèi)存,通常,虛擬機(jī)把這個(gè)任務(wù)交給垃圾收集器。(北大青鳥北京通州校區(qū),軟件技術(shù)培訓(xùn))
垃圾回收
垃圾收集器的主要工作是自動(dòng)回收不在被運(yùn)行的程序所引用的對(duì)象所占用的內(nèi)存。此外,它也可能去移動(dòng)那些還在使用的對(duì)象,以此減少堆碎片。
對(duì)象內(nèi)部表示
Java對(duì)象中包含的基本數(shù)據(jù)由它所屬的類及其所有超類聲明的實(shí)例變量組成。只有有一個(gè)對(duì)象引用,虛擬機(jī)就必須能夠快速定位對(duì)象實(shí)例的數(shù)據(jù)。另外,它必須能通過該對(duì)象引用訪問相應(yīng)的類數(shù)據(jù)(存儲(chǔ)于方法區(qū)的類型信息),在對(duì)象中通常有一個(gè)指向方法區(qū)的指針。
對(duì)象引用可認(rèn)為是一個(gè)本地指針。通過某種策略可由該指針找到實(shí)例數(shù)據(jù)以及class data。
有如下幾個(gè)理由要求虛擬機(jī)必須能夠通過對(duì)象引用得到類數(shù)據(jù)(class data):
1. 當(dāng)程序在運(yùn)行時(shí)需要轉(zhuǎn)換某個(gè)對(duì)象引用為另一種類型,虛擬機(jī)必須能檢查這種轉(zhuǎn)換是否被允許。被轉(zhuǎn)換的對(duì)象是否的確是被引用的對(duì)象或它的超類。
2. 當(dāng)程序執(zhí)行 instanceof操作時(shí),虛擬機(jī)也進(jìn)行了同樣的檢查。(北大青鳥北京通州校區(qū),軟件技術(shù)培訓(xùn))
3. 在程序中調(diào)用某個(gè)實(shí)例方法時(shí),虛擬機(jī)必須進(jìn)行動(dòng)態(tài)綁定。不能按照引用的類型(type of reference),而是按照對(duì)象的實(shí)際類。
因此,虛擬機(jī)必須再次通過對(duì)象的引用去訪問類數(shù)據(jù)。
北大青鳥北京通州校區(qū)