我正在将一些字节写入一个MemoryStream中。我给了它100 MB的尺寸
using (MemoryStream Stream = new MemoryStream())
{
for ( loop 1400 time)
{
func(i, OStream, Stream, );
}
lock (this)
{
Stream.WriteTo(OStream);
}}
func(i, OStream, Stream)
{
loop 19 times
get buffer;
Stream.Write(buffer, 0, buffer.Length);
}缓冲区是一个大小从65536到116454不等的byte[]。我循环了1000次。我把它写在for循环中,但是我得到了OutOfMemoryException异常。
有办法扩展MemoryStream并避免异常吗?
发布于 2017-03-23 11:08:14
考虑到数据量,最小为6,000*65536字节,字节数组为<400 MB,最大为6,000*116454字节,即<700 MB。MemoryStream将在必要时将其大小加倍,因此它首先有100 MB,然后是200 MB,然后是400 MB,可能是800 MB。
即使垃圾收集器无法在中间清理,您也可能认为这是最大的2200 MB (字节数组为700,初始内存流为100,第一次扩展为200,…)。事实上,情况可能是这样,并留下了“足够”的内存。但是,它可能不能在连续块中使用。
您可能面临的是内存碎片问题。大量字节数组往往超过85001字节,因此它们被分配到大型对象堆上。大型对象堆不会被压缩,因此会受到碎片的影响。
您可以在How to use WinDbg to track down .NET OutOfMemoryExceptions尝试使用这个答案。我还发布了一个memory fragmentation example,以防您想要将您的情况与其进行比较。
潜在修复
一个快速的解决方法是将其编译为x64,因为您有更多的内存可用。更清晰的方法取决于您的实际情况,需要对算法进行优化,例如,您可以提前计算所需结果的总大小,这样MemoryStream就不需要将其大小加倍。
使用一个200个kB字节数组并用临时数据重新填充它,而不是到处创建新的数组也可能更好。
如果您的最后任务是将数据写入文件,请使用FileStream并将其直接写入文件。
您还可以完全摆脱MemoryStream,只需将所有字节数组放在一个List<byte[]>中。
也许还有很多其他的解决方案。
https://stackoverflow.com/questions/42973258
复制相似问题