2011-09-18 32 views
0

讓我們想起一個內存泄漏程序,其中堆內存塊未被釋放並且程序終止。如果這是一個Java程序,內置的垃圾回收器會在程序退出之前自動釋放這個堆塊。內存泄漏 - 缺少垃圾回收器

但即使在C++中,如果程序退出,內核是否會自動解除與進程相關的所有空間。同樣在Java代碼中,內核必須爲進程的文本部分(代碼)取消分配空間(即使堆棧和堆部分被垃圾回收器解除分配)。那麼使用垃圾收集器功能的整體優勢 - 只是程序本身而不是內核釋放堆所需的時間節省的增加? (如果有任何這樣的節省)

編輯:我的主要疑問來看看答覆 - 當內存使用量達到極限時,GC會自動調用自己嗎?因爲如果只在程序終止之前調用GC,則對於長程序而言,它不會有用。

+0

如果您的程序要運行很長時間會怎麼樣?在這種情況下,程序可以分配所有可用內存,當然也會失敗。因此,即使操作系統在終止時釋放內存,程序也必須對其分配的內存負責。 – Isaac

+0

這將取決於。在程序中可以隨時調用Java中的GC嗎?通過調用我的意思是它可以自動觸發內存使用量達到極限時?因爲如果只有在程序終止時才調用GC,對於長時間運行的程序來說,這無關緊要。 – Hari

回答

1
  1. 這假定內核在你之後清理完畢。並非所有操作系統都會自動處理動態分配的內存。 (但要公平:至少在桌面上,大多數現代應用都會這樣做)
  2. 即使回收所有內存的操作系統也只能在進程終止時執行。大多數程序在總運行時間內分配的內存要比他們在任何給定時間點需要的時間多得多(當運行時間足夠長時,對於許多數據處理應用程序,「long」可能只有幾秒鐘)。
  3. 因此,許多 - 尤其是長時間運行的進程會在他們的整個生命週期內創造出越來越多的垃圾(不再使用的內存,並且不會再被使用),而沒有任何希望擺脫它沒有終止。你不想爲了保持內存使用率低而重新開始整個過程​​,是嗎?
  4. 因爲未使用的內存幾乎從不(有很多進程無限期地運行並且有些可以運行幾個小時)被處置,所以一段時間後會出現嚴重的內存短缺。您的瀏覽器會將您在此會話期間打開的所有圖像,HTML文檔,JS對象等存儲在內存中,因爲您不會每隔幾分鐘就重新啓動一次。這是廢話和瀏覽器中的嚴重問題,你說?我的確切點。
  5. 此外,大部分(也就是說,所有好的)選區解除分配一切 - 他們不時運行時,他們認爲這是值得的,但是當進程關閉,剩下的一切在內存中被釋放到較低的級別(不管是自定義分配器還是操作系統)。這也是終結者不能保證運行的原因 - 在一個短期運行的程序中,如果分配不足,GC可能永遠不會運行。

所以不,GC不是節約時間。這是關於節省大量的內存,防止長時間運行的分配密集型程序佔用所有可用內存,並最終導致每個人都因內存不足錯誤而死亡。

0

假設程序分配了一些資源,在它運行的所有時間使用它,但在退出之前沒有正確釋放它。當這個程序退出時,內核會釋放所有程序資源 - 這是可以的。

現在考慮一些函數在每次調用時都會造成內存泄漏的情況,並且此函數在一秒鐘內調用100次。幾分鐘或幾小時後,此程序崩潰,因爲沒有可用內存。

不好的一點是程序員造成類型1的內存和資源泄漏,通常會造成類型2的泄漏,從而產生髒和不穩定的代碼。專業程序員用0資源和內存泄漏編寫完美的代碼。如果垃圾收集器可用 - 這是可以的。如果沒有 - 自己管理資源。

順便說一句,它仍然有可能使垃圾回收器泄漏 - 就像衆所周知的.NET事件源消費者泄漏一樣。所以,垃圾收集器非常有用,節省了大量的開發人員時間,但無論如何開發人員必須認真管理程序資源。