內(nèi)存區(qū)域
Java虛擬機在執(zhí)行Java程序的過程中會把他所管理的內(nèi)存劃分為若干個不同的數(shù)據(jù)區(qū)域。Java虛擬機規(guī)范將JVM所管理的內(nèi)存分為以下幾個運行時數(shù)據(jù)區(qū):程序計數(shù)器,Java虛擬機棧,本地方法棧,Java堆,方法區(qū)。
image
具體參考:Java內(nèi)存區(qū)域與內(nèi)存溢出
常用的垃圾回收算法:
-
引用計數(shù)算法:
給對象添加一個引用計數(shù)器,每當(dāng)有一個地方引用它時,計數(shù)器值就加1;當(dāng)引用失效時,計數(shù)器值就減1;任何時刻計數(shù)器值為0 的對象就是不再被使用的,垃圾回收器將收回該對象所使用的內(nèi)存。
引用計數(shù)算法實現(xiàn)簡單,效率很高,微軟的COM技術(shù)、ActionScript、Python等都使用了引用計數(shù)算法進行內(nèi)存管理,但是引用計數(shù)算法對于對象之間相互循環(huán)引用問題難以解決,因此java并沒有使用引用計數(shù)算法。 -
根搜索算法:
通過一系列的名為“GC Root”的對象作為起點,從這些節(jié)點向下搜索,搜索所走過的路徑稱為引用鏈(Reference Chain),當(dāng)一個對象到GC Root沒有任何引用鏈相連時,則該對象不可達(dá),該對象是不可使用的,垃圾收集器將回收其所占的內(nèi)存。
主流的商用程序語言C#、java和Lisp都使用根搜素算法進行內(nèi)存管理。
在java語言中,可作為GC Root的對象包括以下幾種對象:
a. java虛擬機棧(棧幀中的本地變量表)中的引用的對象。
b.方法區(qū)中的類靜態(tài)屬性引用的對象。
c.方法區(qū)中的常量引用的對象。
d.本地方法棧中JNI本地方法的引用對象。
Java中使用的垃圾回收算法:
- 引用計數(shù)法:缺點是無法處理循環(huán)引用問題
- 標(biāo)記-清除法:標(biāo)記所有從根結(jié)點開始的可達(dá)對象,缺點是會造成內(nèi)存空 間不連續(xù),不連續(xù)的內(nèi)存空間的工作效率低于連續(xù)的內(nèi)存空間,不容易分配內(nèi)存
- 復(fù)制算法:將內(nèi)存空間分成兩塊,每次將正在使用的內(nèi)存中存活對象復(fù)制到未使用的內(nèi)存塊中,之后清除正在使用的內(nèi)存塊。算法效率高,但是代價是系統(tǒng)內(nèi)存折半。適用于新生代(存活對象少,垃圾對象多)
- 標(biāo)記-壓縮算法:標(biāo)記-清除的改進,清除未標(biāo)記的對象時還將所有的存活對象壓縮到內(nèi)存的一端,之后,清理邊界所有空間既避免碎片產(chǎn)生,又不需要兩塊同樣大小的內(nèi)存快,性價比高。適用于老年代。
-
分代
詳細(xì)內(nèi)容參考: 深入理解java垃圾回收算法
參考:深入理解 Java 垃圾回收機制