Java垃圾收集学习笔记
(1)除了釋放不再被引用的對象,垃圾收集器還要處理堆碎塊。請求分配新對象時可能不得不增大堆空間的大小,雖然可以使用的空閑空間是足夠的,但是堆中沒有沒有連續的空間放得下新對象??赡軙е绿摂M機產生不必要的”內存不足“錯誤。
(2)使用垃圾收集堆,有一個潛在的缺陷就是加大程序的負擔,可能影響程序的性能。因為虛擬機需要追蹤哪些對象被正在執行的程序引用,還要動態釋放垃圾對象。
(3)程序可以調用System.gc()建議jvm去收集垃圾, 但是不能為垃圾回收機制指定某個對象是不是垃圾。即便調用了gc(),并不會馬上進行垃圾回收,甚至不一定會執行垃圾回收。所有的內存分配和回收權限都在jvm,不在開發人員手里。
可以試試:
public class RubbishRelease {// 類的finalize方法,可以告訴垃圾回收器應該執行的操作,該方法從Object類繼承而來。// 在從堆中永久刪除對象之前,垃圾回收器調用該對象的finalize方法。public void finalize() {System.out.println("the Object is going...");}public static void main(String[] args) {for (int i = 0; i < 100; i++) {// 下面不斷創建對象,但是這些對象都沒有被引用new RubbishRelease();new RubbishRelease();new RubbishRelease();System.gc();}System.out.println("The program is over!");} }運行結果:
(4)垃圾收集算法有很多,但任何垃圾收集算法都必須做兩件事情。首先,它必須檢測出垃圾對象。其次,它必須回收垃圾對象所使用的堆空間并還給程序。
(5)區分活動對象和垃圾的兩個基本方法是引用計數和跟蹤。
(6)引用計數是垃圾收集的早期策略。在這種方法中,堆中每一個對象都有一個引用計數。一個對象被創建了,并且指向該對象的引用被分配給一個變量,這個對象的引用計數被置為1。當任何其他變量被賦值為對這個對象的引用時,計數加1。當一個對象的引用超過了生存期或者被設置一個新的值時,對象的引用計數減1。任何引用計數為0的對象可以被當作垃圾收集。當一個對象被垃圾收集的時候,它引用的任何對象計數值減1。這種方法的好處是,引用計數收集器可以很快地執行,交織在程序的運行之中。這個特性對于程序不能被長時間打斷的實時環境很有利。壞處就是,引用計數無法檢測出循環(即兩個或者更多的對象互相引用)。
(7)跟蹤收集器追蹤從根節點開始的對象引用圖。給追蹤過程中遇到對象以某種方式打上標記。追蹤結束時,未被標記的對象就是無法觸及的,從而被收集。基本的追蹤算法被稱作“標記并清除”,這個名字指出垃圾收集過程的兩個階段。
(8)Java虛擬機的垃圾收集器可能有對付堆碎塊的策略。標記并清除收集器通常使用的兩種策略是壓縮和拷貝。這兩種方法都是快速地移動對象來減少堆碎塊。
(9)壓縮收集器把活動的對象越過空閑區滑動到堆的一端,在這個過程中,堆的另一端出現一個大的連續空閑區。所有被移動的對象的引用也被更新,指向新的位置。
(10)拷貝收集器把所有的活動的對象移動到一個新的區域。在拷貝過程中,被緊挨著布置,這樣可以消除原本它們在舊區域的空隙。即空閑區。一般的拷貝收集器算法被稱為“停止并拷貝”。此方案中,堆被分成兩個區域,任何時候都使用一個區域。對象在同一個區域中分配直到被耗盡。此時,程序執行被中止,堆被遍歷,遍歷時遇到活動的對象被拷貝到另個區域。當停止和拷貝過程結束時,程序恢復執行。依次往復,對于指定大小的堆來說需要兩倍大小的內存,由于任何時候都只使用其中的一半,這就是該方法帶來的代價。
(11)按代收集:根據對象的存活周期(一次垃圾收集為一個周期)的不同將內存劃分為幾塊。一般是把Java堆分為新生代和老年代,這樣就可以根據各個年代的特點采用最適當的收集算法。在新生代中,每次垃圾收集時都發現有大批對象死去,只有少量存活,那就選用拷貝算法,只需要付出少量存活對象的拷貝成本就可以完成收集。而老年代中因為對象存活率高、沒有額外空間對它進行分配擔保,可以使用“標記并清除”算法。
(12)終結方法(finalize),這個在上面第3點也有提到:這個方法是垃圾收集器在釋放對象前必須運行。這個可能存在的終結方法使得任何Java虛擬機的垃圾收集器要完成的工作更加復雜。因為終結方法可能“復活”了某些不再被引用的對象(本身或者其他對象)。
(13)堆中的每一個對象都有三種狀態之一:可觸及的、可復活的以及不可觸及的。可觸及狀態好理解。關于可復活狀態:它在從根節點開始的追蹤圖中不可觸及,但是又可能在垃圾收集器執行某些終結方法時觸及。不僅僅是那些聲明了finalize方法的對象,而是所有的對象都要經過可復活狀態。而不可觸及狀態標志著不但對象不再被觸及,而且也不可能通過任何終結方法復活。不可觸及的對象不再對程序的執行產生影響,可自由地回收它們占據的內存。
(14)對象的強,軟,弱,虛引用。
強引用:如果一個對象具有強引用,垃圾回收器絕不會回收它。當內存空間不足,JVM寧愿拋出OutOfMemoryError錯誤,使程序異常終止,也不會考隨意回收具有強引用的對象來解決內存不足的問題。
軟引用:如果一個對象具有軟引用。如果內存空間足夠。垃圾回收器不會回收它。如果內存不足了,就會回收這些對象的內存。只要垃圾回收器沒有回收它,該對象就可以被程序使用。軟引用可用來實現內存敏感的高速緩存。
弱引用:如果一個對象具有弱引用。當垃圾回收器發現只具有弱引用對象,不管當前內存空間足夠與否,都會回收它的內存。不過,由于垃圾回收器是一個優先級很低的線程,因此不一定會很快發現只具有弱引用的對象。
虛引用:虛引用不會決定對象的生命周期。如果一個對象僅持有虛引用,那么它就和沒有任何引用一樣,在任何時候都可能被垃圾回收器回收。
總結
以上是生活随笔為你收集整理的Java垃圾收集学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 寻迹小车开发日记
- 下一篇: 使用clonezilla(在生龙)克隆系
