1.gc主要發生在堆和方法區,其他區域隨着線程的生滅,內存回收具有確定性。
2.判斷對象是否已死(不可能再被任何途徑使用的對象)
1)引用計數算法
給對象中添加一個引用計數器,每當有地方引用是就加一,當引用失效時,計數器減一,任何時刻計數器爲0的對象就是不可能再被使用的。
缺點:很難解決對象之間的循環引用
2)跟搜索算法
通過一系列稱爲“GC Roots”的對象作爲起始點,從這些節點向下搜索,搜索所走過的路徑稱爲引用鏈,當一個對象到GC Roots沒有任何引用鏈(即GC Roots到對象不可達)時,則證明此對象是不可用的。
在Java語言中,可以作爲GCRoots的對象包括下面幾種:
(1). 虛擬機棧(棧幀中的局部變量區,也叫做局部變量表)中引用的對象。
(2). 方法區中的類靜態屬性引用的對象。
(3). 方法區中常量引用的對象。
(4). 本地方法棧中JNI(Native方法)引用的對象。
3.四種引用類型
4.回收方法區
方法區回收性價比不高
5垃圾收集算法
1)標記清除算法
首先標記出所有需要回收的對象,在標記完成後統一回收掉所有被標記的對象
後續算法都是基於這種思路的改進
缺點一標記和清除過程的效率都不高
二空間問題,標記清除後會產生大量不連續的內存空間,當需要分配較大對象是無法找到足夠大的連續空間而提前觸發垃圾回收
2)複製算法
將內存容量劃分爲大小相等的兩塊,每次只適用其中的一塊,當一塊用完了,就將還活着的對象複製到另一塊上面,把已使用的內存空間一次清理掉。
商業虛擬機採用這種算法來回收新生代。內存空間劃分比例不是一比一,而是分爲Eden和兩個survivor,比例爲8.1
每次使用Eden和一個survivor,把活着的對象複製到另一個survivor,空間不夠使用老年代進行擔保
3)標記整理算法
標記過程與標記清除一樣,後續讓所有存活的對象想一端移動,然後清除掉端邊界以外的內存。
4)分代收集算法
根據對象存活週期的不同將內存劃分爲幾塊,一般把java堆分爲新生代和老年代,根據各個年代的特點採用最適當的收集算法
如新生代複製算法,老年代標記清除或者標記整理
6垃圾收集器