2013-08-23 37 views
4

我的一個主要應用是在運行時崩潰。內存分配 - 15 GB如何等於2GB?

我想知道這是否與系統的內存分配問題有關。因此,我創建了一個小的測試程序來分配1GB內存,同時運行15個這樣的進程,因此總共使用了15GB的RAM。

但是,當我運行這個程序時,任務管理器顯示它只佔用了2GB的RAM?這怎麼可能?

我寫了一個示例代碼如下

char *ptr[1024]; 
for (i = 0 ; i < 1024 ; ++i) 
{ 
    ptr[i] = new char[1024 * 1024]; 
    std::cout << " Allocated 1024 MB" << i << " th time " << std::endl; 
} 
+5

也許操作系統過度使用?即,儘管沒有足夠的內存,'new'會返回一個有效的指針。嘗試*實際*對所獲得的內存寫點東西,你的過程可能會被殺死。 – 2013-08-23 21:05:46

+2

任務管理器不顯示「佔用的內存量」。它顯示[工作集](http://windows.microsoft.com/en-us/windows-vista/what-do-the-task-manager-memory-columns-mean),這是一個不同的事情。 –

回答

8

試着在你的大陣列中存儲數據。 Memset會很好。 如果你沒有觸及它,你可能正在看實際的內存,這些內存仍然只能在虛擬內存中。

+0

謝謝戴爾。通過使用memset解決了難題。 – user373215

+0

這是一件毫無意義的事情,它只會減慢程序速度。 –

+0

@HansPassant:完全沒有,它會將所有頁面錯誤並創建物理頁面。否則,這個分配的內存將僅僅指向一個虛擬零頁面。由於OP希望強制系統分配內存,這是正確的。 – Damon

14

Windows是需求分頁的虛擬內存操作系統。用operator new分配內存只分配虛擬內存。你不會開始使用物理內存,RAM,直到你實際上訪問的內存。你沒有這樣做。

您可以強制RAM通過觸摸每4096字節分配,更好地作出這樣寫,否則將被優化掉:

size_t size = 1024 * 1024; 
    ptr[i] = new char[size]; 
    for (size_t j = 0; j < size; j += 4096) ptr[i][j] = 0; 

但是,這是相當做無意義的事情,它只是減緩你的程序關閉。並沒有真正測試任何東西,一個進程不能在Windows上耗盡內存。將任務管理器放入編程器模式,添加提交大小列。這是真實的數字。

+0

請注意,它確實可以確保空間在必要時可用。與某些操作系統不同,後者不得不開始殺死人們以滿足內存需求。 –

+0

@Hans Passant:我想你有一個鏈接到技術背景。 –

+0

我認爲,延期分配是愚蠢的。 –

1

也許操作系統overcommits,我。即,operator new返回有效(非NULL)指針,雖然沒有足夠的內存。嘗試實際上是爲獲得的內存寫入,並且您的進程可能會被終止(或至少物理內存使用量增加)。

0

http://en.wikipedia.org/wiki/Virtual_memory

你基本上是用數據填充你的頁面文件。操作系統發現你正在分配大量數據,但在使用它之前,這些數據不會從頁面文件中拉出到主內存中。

1

操作系統(無論是Windows,Linux還是MacOS)並不指望所有分配內存的進程都實際使用所有內存。許多程序都會執行諸如分配1MB來保存文件,然後用14KB文件數據填充文件(因爲它比計算文件大小和實際分配適量容易)。因此,並不需要花費所有的努力來真正爲真正的物理內存頁面提供可用於不可用的內存,而只是將其分配到虛擬空間中,然後在實際使用內存時找到一些物理內存。

因此,任務管理器中顯示的內存量只是您使用的實際內存量,而不是您已分配但從未使用的內存量。

如果你寫一個循環寫入你的分配中的第256或1024字節,它應該「增長」並顯示你分配的實際內存量。