SessionStateItemCollection中的意外OutOfMemoryException反序列化

时间:2016-08-31 10:05:15

标签: c#

我有一个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

为什么会发生该异常(使用该调用堆栈)?

1 个答案:

答案 0 :(得分:1)

由于此对象的序列化特性,如果您查看SessionStateItemCollection.Deserialize方法,您将找到以下代码:

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

在你的情况下,count等于543449410,这是一个块中超过2 GB的内存。