[.NET] System.OutOfMemoryException 記憶體不足

X86 vs X64

最近客戶端IT回報在測試環境執行Console程式時發生記憶體不足的問題,初步確認環境:

1.測試機裝Windows Server 2008 R2 x64版,配置8GB記憶體。

2.執行時記憶體使用率15%上下,但發生OutOfMemory Exception。

3.建置時平台目標的選項,客戶回答也是Any CPU。

聽起來沒古怪,在測試機上執行時,IL應該會載入成X64 Native Code執行,

於是請客戶再執行1次,然後觀察工作管理員突然電話的那頭傳出驚訝的聲音:是32位元也

嗯,原來主要商業的類別庫選Any CPU 應該是會搭配作業系統以64bit執行,但裝載的Console專案中有另一位客戶IT增加了一個元件參考,

因為引用只有32bit版本,所就手動調整了建置的選項到32bit(x86)。

好,眼見為憑的問題找到了,接下來客戶和我都想了解,32 Bit程式可定址的記憶體空間應該可以到4G,怎麼吃到1G多就吃不下了,

於是默默回來家裡做實驗:

實驗1: 

編譯成x64,然後執行一支製作堆積(heap)的程式

組態檔案 gcAllowVeryLargeObjects = True

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
  <runtime>
    <gcAllowVeryLargeObjects enabled="true"></gcAllowVeryLargeObjects>
  </runtime>
</configuration>

 

如果記憶體配置夠,可以吃好飽。

實驗2: 

編譯成x86,然後執行製作堆積(heap)的程式

呼~吃到1.7G就顯示記憶體不足了,真的不是以前2*32 (4G)的理所當然也。

紀錄:

1.後來從黑大的文章發現: 32bit下,2G屬作業系統專用(Kernel Mode),程式(User Mode)存取的只有2GB,再扣除一些基本需求,就剩1G多了。

2.stackoverflow有神人用editbin.exe + vsvars32.bat 將32 bit程式執行檔吃到3G多記憶體,因為電腦內少了VC的安裝,以後有時間再測試。

3.Visual Studio偵錯模式下,x86程式只吃到1.3G記憶體就飽了