我有一个XY问题。我目前正在努力学习和了解Y本身的情况。要重现我的场景,请使用此代码(以及对System.Web 4.0的引用)创建一个新的控制台应用程序:
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];
}
它不抛出OutOfMemoryException
。
为什么会发生该异常(使用该调用堆栈)?
答案 0 :(得分:1)
由于此对象的序列化特性,如果您查看SessionStateItemCollection.Deserialize方法,您将找到以下代码:
int count = reader.ReadInt32();
...
new SessionStateItemCollection.KeyedCollection(count)
在你的情况下,count等于543449410,这是一个块中超过2 GB的内存。