建設(shè)網(wǎng)站實驗活動小結(jié)百度快速排名優(yōu)化工具
JVM 內(nèi)存分哪幾個區(qū),每個區(qū)的作用是什么?
java 虛擬機主要分為以下一個區(qū):方法區(qū):
1. 有時候也成為永久代,在該區(qū)內(nèi)很少發(fā)生垃圾回收,但是并不代表不發(fā)生?GC,在這里進行的?GC
主要是對方法區(qū)里的常量池和對類型的卸載
2. 方法區(qū)主要用來存儲已被虛擬機加載的類的信息、常量、靜態(tài)變量和即時編譯器編譯后
的代碼等數(shù)據(jù)。
3. 該區(qū)域是被線程共享的。
4. 方法區(qū)里有一個運行時常量池,用于存放靜態(tài)編譯產(chǎn)生的字面量和符號引用。該常量池具有動態(tài)
性,也就是說常量并不一定是編譯時確定,運行時生成的常量也會存在這個常量池中。
虛擬機棧:
1. 虛擬機棧也就是我們平常所稱的棧內(nèi)存,它為?java 方法服務(wù),每個方法在執(zhí)行的時候都
會創(chuàng)建一個棧幀,用于存儲局部變量表、操作數(shù)棧、動態(tài)鏈接和方法出口等信息。
2. 虛擬機棧是線程私有的,它的生命周期與線程相同。
3. 局部變量表里存儲的是基本數(shù)據(jù)類型、returnAddress 類型(指向一條字節(jié)碼指令的地址)和對象
引用,這個對象引用有可能是指向?qū)ο笃鹗嫉刂返囊粋€指針,也有可能是代表對象的句柄或者與對
象相關(guān)聯(lián)的位置。局部變量所需的內(nèi)存空間在編譯器間確定
4. 操作數(shù)棧的作用主要用來存儲運算結(jié)果以及運算的操作數(shù),它不同于局部變量表通過索引來訪問,
而是壓棧和出棧的方式
5. 每個棧幀都包含一個指向運行時常量池中該棧幀所屬方法的引用,持有這個引用是為了支持方法調(diào)
用過程中的動態(tài)連接.動態(tài)鏈接就是將常量池中的符號引用在運行期轉(zhuǎn)化為直接引用。
本地方法棧
本地方法棧和虛擬機棧類似,只不過本地方法棧為?Native 方法服務(wù)。
堆
java 堆是所有線程所共享的一塊內(nèi)存,在虛擬機啟動時創(chuàng)建,幾乎所有的對象實例都在這里創(chuàng)建,因此
該區(qū)域經(jīng)常發(fā)生垃圾回收操作。
程序計數(shù)器
內(nèi)存空間小,字節(jié)碼解釋器工作時通過改變這個計數(shù)值可以選取下一條需要執(zhí)行的字節(jié)碼指令,分支、
循環(huán)、跳轉(zhuǎn)、異常處理和線程恢復(fù)等功能都需要依賴這個計數(shù)器完成。該內(nèi)存區(qū)域是唯一一個?java 虛擬
機規(guī)范沒有規(guī)定任何?OOM 情況的區(qū)域。
如和判斷一個對象是否存活?(或者 GC 對象的判定方法)
判斷一個對象是否存活有兩種方法:
1. 引用計數(shù)法
所謂引用計數(shù)法就是給每一個對象設(shè)置一個引用計數(shù)器,每當(dāng)有一個地方引用這個對象時,就將計數(shù)器
加一,引用失效時,計數(shù)器就減一。當(dāng)一個對象的引用計數(shù)器為零時,說明此對象沒有被引用,也就是
“死對象”,將會被垃圾回收.引用計數(shù)法有一個缺陷就是無法解決循環(huán)引用問題,也就是說當(dāng)對象?A 引用對象?B,對象B 又引用者對
象?A,那么此時?A,B 對象的引用計數(shù)器都不為零,也就造成無法完成垃圾回收,所以主流的虛擬機都沒
有采用這種算法。
2. 可達性算法(引用鏈法)
該算法的思想是:從一個被稱為 GC Roots 的對象開始向下搜索,如果一個對象到?GC Roots 沒有任何
引用鏈相連時,則說明此對象不可用。
在?java 中可以作為?GC Roots 的對象有以下幾種:
· 虛擬機棧中引用的對象
· 方法區(qū)類靜態(tài)屬性引用的對象
· 方法區(qū)常量池引用的對象
· 本地方法棧?JNI 引用的對象
雖然這些算法可以判定一個對象是否能被回收,但是當(dāng)滿足上述條件時,一個對象比不一定會被回收。
當(dāng)一個對象不可達?GC Root 時,這個對象并
不會立馬被回收,而是出于一個死緩的階段,若要被真正的回收需要經(jīng)歷兩次標記
如果對象在可達性分析中沒有與?GC Root 的引用鏈,那么此時就會被第一次標記并且進行一次篩選,篩
選的條件是是否有必要執(zhí)行?finalize()方法。當(dāng)對象沒有覆蓋?finalize()方法或者已被虛擬機調(diào)用過,那么
就認為是沒必要的。
如果該對象有必要執(zhí)行?finalize()方法,那么這個對象將會放在一個稱為?F-Queue 的對隊列中,虛擬機
會觸發(fā)一個?Finalize()線程去執(zhí)行,此線程是低優(yōu)先級的,并且虛擬機不會承諾一直等待它運行完,這是
因為如果?finalize()執(zhí)行緩慢或者發(fā)生了死鎖,那么就會造成?F- Queue 隊列一直等待,造成了內(nèi)存回收
系統(tǒng)的崩潰。GC 對處于?F-Queue 中的對象進行
第二次被標記,這時,該對象將被移除”即將回收”集合,等待回收。