2012-08-12 56 views
4

我們有一個應用程序,可能會分配大量的小對象(取決於用戶輸入)。有時候應用程序耗盡內存並且崩潰。但是,如果我們知道內存分配變得緊張,那麼會存在一些優先級較低的對象,這些對象可能會被破壞,從而使我們能夠正常降級用戶結果。檢測內存運行低前在Windows分配開始失敗

在調用'new'失敗之前,檢測進程內存的最佳方式是什麼?我們可以調用API函數,如GetProcessWorkingSetSize()GetProcessMemoryInfo(),但您如何知道何時達到給定機器的限制(例如,最大分配的80%)?

+1

除非你的硬盤快滿了,這個問題是不是在釋放內存的機器上的金額(因爲你有虛擬磁盤上的內存),但地址空間碎片是由於這些對象和可能的內存泄漏。 – 2012-08-12 12:37:49

+0

@AlexeyFrunze在32位Windows內存分配似乎開始失敗大約1.5GB。這不是內存泄漏,我們可以解釋所有使用過的內存,但是我關於碎片的看法。 – snowdude 2012-08-13 09:00:38

回答

4
  • 在啓動時,分配一個內存儲備。
  • 然後使用set_new_handler()安裝一個會檢測到分配失敗的鉤子。
  • 當發生下列情況時:
    • 釋放儲備(所以你有足夠的可用內存來處理)。
    • 運行你的代碼,找到並釋放低優先級的對象。
    • 當它完成它的工作時,嘗試再次重新分配儲備(下次)。
    • 最後返回讓原始分配嘗試重試。
+0

謝謝,好主意。 – snowdude 2012-08-13 09:01:22

0

檢查答案Win32/MFC: How to find free memory (RAM) available?

您需要定期查找可用空閒內存並在某些限制下停止分配。 正如上面提到的答案中所述,您可以使用GlobalMemoryStatusEx和/或VirtualQueryEx

+0

通常不是一個好主意。見http://blogs.msdn.com/b/oldnewthing/archive/2012/01/18/10257834.aspx – 2012-08-13 05:57:04

+0

@HarryJohnston好點。但這是問題還是這個特殊的答案? – Rohan 2012-08-13 06:13:25

+0

我認爲我們的問題是微妙的不同。我們不關心操作系統即將停止分配我們的程序內存時我們只想知道的全局系統資源,所以我們可以在它太遲之前做些什麼。 – snowdude 2012-08-13 09:08:58

2

如果它是一個32位的進程,那麼你會希望確保不要超過1.6GB,這是2.0GB的80%,這是你的進程所允許的最大值。調用GlobalMemoryStatusEx將填充結構MEMORYSTATUSEX.ullAvailVirtual,當這隻有400MB可用(或更少),那麼你是在你的門檻。