2016-08-31 82 views
0

我有一個XY問題。我目前正在嘗試學習和理解Y本身發生了什麼。要重現我的情況下,請用這個代碼創建一個新的控制檯應用程序(和System.Web程序4.0參考):SessionStateItemCollection中的意外OutOfMemoryException反序列化

var badData = new byte[] { 66, 97, 100, 32, 68, 97, 116, 97 }; 

using (var ms = new MemoryStream(badData)) 
using (var br = new BinaryReader(ms)) 
{ 
    var item = SessionStateItemCollection.Deserialize(br); // <-- OOMException here 
} 

Console.ReadKey(); 

我再次意識到,有一個與此代碼種種問題,但是我走之前回到X和/或開始修復實際問題,我想瞭解爲什麼OutOfMemoryException發生。

我試着回答我自己的問題,首先用常識,但我可以想到沒有理由說爲什麼說代碼會消耗大量的內存?

所以下次我已經嘗試通過查看調用堆棧來回答我的問題,這就是:

mscorlib.dll!System.Collections.ArrayList.ArrayList(int capacity) + 0x1f bytes  
System.dll!System.Collections.Specialized.NameObjectCollectionBase.Reset(int capacity) + 0x21 bytes 
System.Web.dll!System.Web.SessionState.SessionStateItemCollection.Deserialize(System.IO.BinaryReader reader) + 0x75 bytes 
ConsoleApplication1.exe!ConsoleApplication1.Program.Main(string[] args) Line 20 + 0x9 bytes C# 

所以我檢查了the source of System.Collections.ArrayList's relevant constructor與此代碼:

public ArrayList(int capacity) { 
    if (capacity < 0) throw new ArgumentOutOfRangeException("capacity", Environment.GetResourceString("ArgumentOutOfRange_MustBeNonNegNum", "capacity")); 
    Contract.EndContractBlock(); 

    if (capacity == 0) 
     _items = emptyArray; 
    else 
     _items = new Object[capacity]; 
} 

它確實是而不是 throw OutOfMemoryException

爲什麼會發生該異常(使用該調用堆棧)?

回答

1

因爲此對象的序列化性質的,如果你看看SessionStateItemCollection.Deserialize方法,你會發現下面的代碼:

int count = reader.ReadInt32(); 
... 
new SessionStateItemCollection.KeyedCollection(count) 

在你的情況計數等於543449410,這是超過2 GB的內存一大塊。