Java程序設計(三)垃圾回收機制

今天,我們來談談Java這門語言的垃圾回收機制。首先,我們需要去回想下,在C++中,是如何處理內存的問題,換句話說,C++是如何處理沒有使用的對象以及對象垃圾的問題的,對於C++來說,當你在使用對象的時候,好,這沒問題,問題是在對象使用完之後呢,怎麼去處理這個內存空間呢?對象通過new 出來之後呢,便會一直存在在這所指定的空間中,一直到程序結束,或者說,使用類的析構函數去處理這new 出來的對象,開闢的空間。C++並不會自動的去處理這個問題,而是留給編程員去處理這個問題,因此我們常常使用析構函數去處理這塊使用之後的廢棄空間,這對於程序員來說,顯然是一件麻煩的事兒,可是C++就是這樣的,一切都要我們去建立析構函數去主動的處理這個廢棄的問題。這是個在C++的麻煩中的一點。

對於Java來說,顯然比C++做的人性化的太多,Java引進了垃圾回收機制,這樣的話,就可以不用我們程序員過多的關注內存的問題,而是關注程序本身。那麼下面我就和大家詳細介紹一下,java的垃圾回收機制。

·1.什麼是垃圾回收機制?

在Java 中,如果對象沒有其所指的引用或者說引用沒有指向其分配的內存塊。無法通過變量進行參考。通俗的說,其指向不定,內存塊沒有所有者,無法指定其對象,這樣的時候,Java的系統線程將自動尋找這類垃圾,並自動回收,這就是垃圾回收機制。

2.垃圾回收機制的算法實現(大概瞭解,不作要求)

2.1. 引用計數法(Reference Counting Collector)
  引用計數法是唯一沒有使用根集的垃圾回收的法,該算法使用引用計數器來區分存活對象和不再使用的對象。一般來說,堆中的每個對象對應一個引用計數器。當每一次創建一個對象並賦給一個變量時,引用計數器置爲1。當對象被賦給任意變量時,引用計數器每次加1當對象出了作用域後(該對象丟棄不再使用),引用計數器減1,一旦引用計數器爲0,對象就滿足了垃圾收集的條件。
  基於引用計數器的垃圾收集器運行較快,不會長時間中斷程序執行,適宜地必須實時運行的程序。但引用計數器增加了程序執行的開銷,因爲每次對象賦給新的變量,計數器加1,而每次現有對象出了作用域生,計數器減1
2.2. tracing算法(Tracing Collector)
tracing算法是爲了解決引用計數法的問題而提出,它使用了根集的概念。基於tracing算法的垃圾收集器從根集開始掃描,識別出哪些對象可達,哪些對象不可達,並用某種方式標記可達對象,例如對每個可達對象設置一個或多個位。在掃描識別過程中,基於tracing算法的垃圾收集也稱爲標記和清除(mark-and-sweep)垃圾收集器.
2.3. compacting算法(Compacting Collector)
  爲了解決堆碎片問題,基於tracing的垃圾回收吸收了Compacting算法的思想,在清除的過程中,算法將所有的對象移到堆的一端,堆的另一端就變成了一個相鄰的空閒內存區,收集器會對它移動的所有對象的所有引用進行更新,使得這些引用在新的位置能識別原來的對象。在基於Compacting算法的收集器的實現中,一般增加句柄和句柄表。
2.4. copying算法(Coping Collector)
  該算法的提出是爲了克服句柄的開銷和解決堆碎片的垃圾回收。它開始時把堆分成一個對象區和多個空閒區,程序從對象區爲對象分配空間,當對象滿了,基於coping算法的垃圾回收就從根集中掃描活動對象,並將每個活動對象複製到空閒區(使得活動對象所佔的內存之間沒有空閒間隔),這樣空閒區變成了對象區,原來的對象區變成了空閒區,程序會在新的對象區中分配內存。
  一種典型的基於coping算法的垃圾回收是stop-and-copy算法,它將堆分成對象區和空閒區域區,在對象區與空閒區域的切換過程中,程序暫停執行。
2.5. generation算法(Generational Collector)
stop-and-copy垃圾收集器的一個缺陷是收集器必須複製所有的活動對象,這增加了程序等待時間,這是coping算法低效的原因。在程序設計中有這樣的規律:多數對象存在的時間比較短,少數的存在時間比較長。因此,generation算法將堆分成兩個或多個,每個子堆作爲對象的一代 (generation)。由於多數對象存在的時間比較短,隨着程序丟棄不使用的對象,垃圾收集器將從最年輕的子堆中收集這些對象。在分代式的垃圾收集器運行後,上次運行存活下來的對象移到下一最高代的子堆中,由於老一代的子堆不會經常被回收,因而節省了時間。
2.6. adaptive算法(Adaptive Collector)
  在特定的情況下,一些垃圾收集算法會優於其它算法。基於Adaptive算法的垃圾收集器就是監控當前堆的使用情況,並將選擇適當算法的垃圾收集器。

3.垃圾回收機制的finalize()方法

步驟通常爲:

尋找垃圾->找到無用垃圾->調用屬於java.lang.Object類中的finalize()方法完成清理前的準備工作->清理內存->回收處理

4..垃圾回收處理機制的特點

4.1由於算法不同 JVM 的不同  各種原因 垃圾回收發生的時間不定 這屬於不可預見的性質

4.2垃圾回收處理的精確性 能精確的找到活着的對象以及要回收的對象

4.3算法多樣性 以及 收集器的多樣性 



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章