第五章.初始化和清理 終結處理和垃圾回收

導論:

  • 將一個對象初始化後就“棄之不顧”的做法並非總是安全的。雖然java用垃圾回收器回收無用對象佔用的內存資源。但也有特殊情況,
    假定對象並非使用new獲得了一塊“特殊”的區域,由於垃圾回收器只知道釋放那些經由new分配的內存,所以他不知道該怎樣釋
    放這塊“特殊”的內存。

1.finalize()

  • 此方法出現的原因:回收除以new方法創建對象方式以外的方式分配的內存
  • 爲了應對上面的那種情況,java允許在類中定義一個名爲finalize()的方法。
  • 工作原理:一旦垃圾回收器準備好釋放對象佔用的存儲空間,將首先調用其finalize()方法,並且在下一次垃圾回收動作發生時,纔會真正回收對象佔用的內存。
  • 潛在編程陷阱:
    對象可能不被垃圾回收
    垃圾回收並不等於“析構”
  • 只要程序沒有瀕臨存儲空間用完的那一刻,對象佔用的空間就總也得不到釋放。如果程序結束,並且對象佔用的存儲空間一直沒有被垃圾回收器回收,則會隨着
    程序的退出,那些資源也會全部交還給操作系統。
  • 之所以使用finalize()方法,大多數是發生在使用“本地方法c”的情況下。
    所以不要過多的調用finalize()方法。它是處理特殊情況的清理工作的。                             

垃圾回收並不能完全代替析構函數,如果想進行出釋放存儲空間之外的清理工作,還是得明確的調用某個恰當的Java方法。

無論是垃圾回收還是終結,都不保證一定發生。如果Java虛擬機並未面臨內存耗盡時,它是不會浪費時間去執行垃圾回收以回覆內存的。

  • 只要程序中存在沒有被適當清理的部分,程序就存在很隱晦的缺陷。使用finalize()方法發現這種缺陷。因爲他總是在對象被回收前調用。

2.垃圾回收器是如何工作的

  • 垃圾回收器對於提高對象的創建速度,有明顯的效果
  • 存儲空間的釋放會影響存儲空間的分配?這確實java虛擬機的工作方式。
  • 在某些java虛擬機上:堆的分配更像一個傳送帶,每分配一個新對象,他就往前移動一個。這意味着分配的速度非常快。java“堆指針”只是簡單的移動到尚未分配的區域,效率非常高。
    然而,實際上java中的堆未必完全像傳送帶那樣工作。要是真的那樣的話,勢必會導致頻繁的內存頁面調度——將其移進移出硬盤。頁面的調度會顯著的影響性能,最終,在創建了足
    夠多的對象後,內存資源將耗盡。
    解決的方法就是垃圾回收器,當它工作時,將一面回收空間,一面使堆中的對象緊湊排列,這樣“堆指針”就可以很容易移動到更靠近傳送帶的開始出,也就避免了頁面錯誤的調度。
  • 通過垃圾回收器對對象重新排列,實現了一種高速的、有無限空間可供分配的對模型。

3.其他系統中的垃圾回收機制【第90頁】

  1. 引用計數模式
  2. 自適應垃圾回收技術
  3. 複製式回收器
  4. 標記-清掃
  5. 停止-複製
  6. 及時編譯計數
  7. ······還有好多(或許自己也可以創造出來一種)


















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