2009-06-01 38 views
26

垃圾收集器可以爲.NET進程分配的最大內存量是多少?當我編譯爲x64時,Process.GetCurrentProcess.MaxWorkingSet返回大約1,4GB,但是當我編譯爲AnyCPU(x64)時,將返回相同的數字。對於x64,它應該更像是任務管理器中顯示的「限制」值。我如何獲得正確的數字,當超出所有情況下都會導致OutOfMemory異常?.NET進程可以分配的最大內存

一些例子的方法應該返回什麼:

1)機器配置:x64的Windows,4GB的物理內存,4GB頁面文件
-As 64位進程:8GB
-As 32位進程:1.4GB

2)機配置:x64的Windows,1GB物理內存,2GB頁面文件
-As 64位過程:3GB
-As 32位過程:1.4GB

3)機器配置:X32-的Windows,4GB的物理內存,4GB頁面文件
-As 64位進程:不會發生
-As 32位進程:1.4GB

4)機器配置: X32-的Windows,512MB的物理內存,512MB的頁面文件
-As 64位進程:不會發生
-As 32位進程:1.0GB

+0

這裏有一篇有趣的文章,討論.NET進程開始看到內存異常的理論最大值和範圍:http://blogs.msdn.com/b/ tom/archive/2008/04/10/chat-question-memory-limits-for-32-bit-and-64-bit-processes.aspx – 2014-05-29 18:22:54

回答

3

不它取決於你有多少RAM ?

理論上,一個x64進程可以分配EB的內存(etabytes?),我認爲 - 即一個LOT。但是,如果你這樣做,你的機器應該開始瘋狂分頁,一般都會死機。

它在32位模式下是不同的,因爲你不能在Windows的任何進程中分配超過1GB的內存(是的,它周圍有方法,但並不漂亮)。實際上,每個.NET過程大約需要7-800meg,因爲.NET保留了一些空間。

無論哪種方式,在32位中,最多可以使用3GB - 操作系統爲自己保留1GB的虛擬空間。

在64位,它應該是2^64,這是一個很大的數字,但http://en.wikipedia.org/wiki/X86-64表示它是256TB的虛擬空間,以及1TB的REAL RAM。無論哪種方式,它都比你的機器中可能存在的要多得多,所以它會打到頁面文件。

隨着64位操作系統和一個64位的運行時, 2.0基於.NET應用程序現在可以利用 用於數據 如基於服務器的高速緩存500倍以上的存儲器。

這有一些好的信息,也http://www.theserverside.net/tt/articles/showarticle.tss?id=NET2BMNov64Bit

順便說一句,如果你是一個64位的機器(即,64機+ x64操作系統)上,編制了AnyCPU和x64做同樣的事情 - 它運行在x64模式。唯一的區別是,如果你使用AnyCPU VRS 86:

  • 64 OS/.NET,AnyCpu:64位應用程序
  • x64操作系統/。NET,64:64的應用程式
  • x64操作系統/ .NET,X32:X32應用程序(64 .NET作爲Fx相BOTH x32或x64的版本安裝框架)

  • X32 OS/NET,AnyCPU:X32應用程序

  • x32 OS/.NET,x64:破壞和燒傷嬰兒! (實際上,它只是優雅地死去)
  • x32 OS/.NET,x32:x32應用程序。
+0

但是我怎樣才能得到一臺機器的真實內存限制? – Rauhotz 2009-06-01 12:15:38

+0

我標記你的答案不好,因爲你混雜了一切。 3代表內存是可以存活一個或多個進程的最大可用物理內存。任何進程都可以訪問完整的4個演出空間(32位地址),無法在物理內存中的內存將被緩存(如果緩存設置正確)。而3演出也不完全是真實的。你必須設置XP,默認情況下,應用程序只有2個RAM,對於OS(物理內存)只有2個RAM。 – 2011-10-26 02:02:36

17

Windows可以配置爲按需分配更多頁面文件空間,或on request
Job objects可以防止消耗超過一定量的內存。
碎片堆和它的代性質(加上需要投入大量的東西在大對象堆)

的所有這些意味着硬限制是不是在現實多大用處,並指回答「如何我理論上可以分配多少內存「比你想象的要複雜得多。

因爲它是複雜的人這個問題可能是試圖做一些事情錯誤,並應他們的問題重定向到更有用的東西。

你想做什麼似乎需要這樣一個問題?

「我只是想知道什麼時候該進程的當前內存負載能拿問題 所以我可以像釋放自定義緩存的一些項目的動作。」

沒錯。這個問題更容易處理。在複雜的順序

兩個解決方案:

  1. 讓你的緩存使用WeakReferences
    • 這意味着事情會被系統幾乎奇蹟般地爲你解脫出來,但你將擁有的東西像小控制替換策略
    • 這依賴於緩存的數據比密鑰的密鑰和開銷都大很多
  2. 註冊爲notification of Garbage Collections
    • 這使您可以控制釋放事物。
    • 您依賴的系統具有合適的GC代最大尺寸,可能需要一段時間才能達到穩定狀態。

注意事項。 它真的確實比重新計算/重新請求數據維護這個海量緩存(通過它的聲音進入磁盤)更便宜。
如果您的緩存在通常/連續請求的項目之間顯示較差的位置,那麼將花費很多努力來分頁數據。具有有效調整的重新定位策略的較小的緩存具有顯着更好的性能(並且對其他正在運行的程序的影響要小得多)

另外:在.Net中,沒有可變大小的對象(字符串,數組)由於內存管理的核心CLR結構的限制,大小超過2GB。 (並且上述任一解決方案都將從中受益)