2011-07-27 111 views
2

我知道每個進程都有自己的操作系統分配的地址空間。所以當程序終止時,整個地址空間被標記爲無效(或者可以自由地再次使用)。現在,如果上述過程泄漏內存,程序終止後它會有什麼區別嗎?內存泄漏和操作系統

也就是說,如果我的程序在某段時間後終止或者以持續的開始 - 結束機制在短時間間隔內運行,那麼內存泄漏會有多大的區別? (我假設泄漏不足以導致平均系統抖動)

我知道泄漏是不好的 - 但我的問題源於這樣的觀點:假設一個對象正在被用於代碼的最終例程 - 不會固定泄漏有什麼不同,因爲過程將在此之後終止?

感謝提前:)

+0

取決於操作系統 –

+0

AFAIR,在Windows NT中終止進程將釋放它所使用的任何內存,無論是否泄漏。不確定在其他操作系統上。 –

+0

是否意味着某些操作系統會按原樣離開地址空間,除非所有動態分配的空間都被明確釋放?那需要一些機制來維護這樣的清單,不是嗎? – sandt1g3r

回答

1

這是一個非常依賴操作系統的問題。

在使用虛擬內存的現代化多操作系統(如:Windows 7中,Linux的),這是事實,所有的(OK,不是所有,但我們不要被挑剔的位置)的資源是特定工藝和將在過程終止時被釋放回系統。

因此,如果你的程序「泄漏內存」,這是否重要?那麼,這取決於它是如何做到的。

如果你在啓動時分配了一堆資源,沒有關係,如果你在關機時手動釋放它們,或者讓操作系統這樣做,它並不重要。我承認自己是一個懶惰的程序員,他喜歡讓操作系統處理這些事情。但是,如果您在運行時出於某種原因在循環或按需分配資源,並且不打算以某種方式管理它們,那麼理論上如果您讓程序運行足夠長時間,它將不斷「泄漏」資源,直到沒有更多的剩餘資源分配爲止。這是一個壞事。不要這樣做。

現在有很多平臺不這樣做。如果您最終做了嵌入式工作,那麼您很可能最終在一個必須管理自己的所有資源(手動釋放內存,關閉文件句柄等)的平臺上。

+0

確實有一些資源,即使Windows在您的流程終止時也不會釋放,並且您預計會手動處理,但是對於那些處於邊緣情況的人來說,您是正確的。在這些情況下,養成處置您分配或打開的任何資源的習慣總是最佳做法。就像穿過你的Ts並點擊你的Is一樣。懶惰的藉口很少;在添加初始化代碼的同時添加清理代碼。它也有助於檢查錯誤。 –

+0

@Cody Gray - 這是一個非常有效的觀點。我不是說錯了,但它不適合我。問題是(至少對我來說)我編寫的任何代碼都有可能存在缺陷,包括資源清理代碼(實際上,這樣的代碼似乎特別容易出錯)。幾乎任何時候我正在編寫代碼,我正在引入錯誤。在這種情況下,如果我放棄操作系統,操作系統就會很好地執行良好的代碼。幾乎所有時間我的首要目標都是儘可能少寫代碼。當我不需要時,我不會爲我的程序添加更多錯誤。 –

+0

......所有這些都說了,我足夠的一個整潔的怪胎(和前童子軍),我很欣賞那些願意付出代價(額外的編碼時間/錯誤/調試),以確保他們離開他們的人處理「營地」的方式與他們發現它的方式相同。 –

0

與分離內核和用戶空間和內存管理器,其中每一個用戶進程只看到虛擬內存(如你所說)現代的操作系統,一般確實是不可能的任何給定的用戶進程都會傷害操作系統(當然不包括特權用戶故意搞亂系統內存的事情)。這就是多進程多任務操作系統的全部理念:由操作系統管理許多同時進程,而不必依靠進程間的協作。 (也就是說,如果內存泄漏是由於無效的訪問錯誤導致的,那麼您仍然容易受到代碼注入的影響,這可能會因系統其他部分的特權提升漏洞而進一步惡化,因此進程的隔離只會發生到目前爲止)。

0

如果你只是抓住了一堆比你應該真正需要的更多的堆,當進程退出時它將被回收。

我不清楚你在這種情況下如何知道你正在泄漏記憶,但假設你確實這樣做了,那麼你應該仍然修復它。這是代碼中的定時炸彈。爲什麼

兩個例子:

  1. 你有可能會在其他地方重複使用的代碼,或者通過剪切和粘貼或重構。
  2. 你可能有可擴展性問題:

    的(有些東西在列表) 做了一些工作泄漏100個字節

現在你重複10次,泄漏1000個字節,終止,沒有大不了。在未來,您將接觸10,000次,並且由於內存不足而導致基本的關閉工作失敗...

+0

說Valgrind報告它,我懶得追查整個事情 - 但在調用堆棧中,我看到它在我的main()中的最後一個例程。 – sandt1g3r