fla*_*ayn 14 c# memory wcf out-of-memory large-object-heap
我必须使用WCF通过不可靠的连接在计算机之间传输大文件.
因为我希望能够恢复该文件,并且我不希望受到WCF的文件大小限制,我将这些文件分块为1MB.这些"块"以流的形式传输.到目前为止哪个效果很好.
我的步骤是:
我的问题在第2步.我假设当我从字节数组创建一个内存流时,它将最终在LOH上并最终导致outofmemory异常.我实际上无法创建此错误,也许我的假设是错误的.
现在,我不想在消息中发送byte [],因为WCF会告诉我数组大小太大.我可以更改允许的最大数组大小和/或我的块的大小,但我希望有另一种解决方案.
我的实际问题:
顺便说一句:在接收端,我简单地从到达流中读取较小的块并将它们直接写入文件,因此不涉及大字节数组.
编辑:
当前解决方案
for (int i = resumeChunk; i < chunks; i++)
{
byte[] buffer = new byte[chunkSize];
fileStream.Position = i * chunkSize;
int actualLength = fileStream.Read(buffer, 0, (int)chunkSize);
Array.Resize(ref buffer, actualLength);
using (MemoryStream stream = new MemoryStream(buffer))
{
UploadFile(stream);
}
}
Run Code Online (Sandbox Code Playgroud)
Joe*_*nds 35
我希望这没关系.这是我在StackOverflow上的第一个答案.
是绝对的,如果你的chunksize超过85000字节,那么数组将在大对象堆上分配.您可能不会很快耗尽内存,因为您正在分配和释放大小相同的连续内存区域,因此当内存填满运行时可以将新块装入旧的回收内存区域.
我会有点担心Array.Resize调用,因为这将创建另一个数组(请参阅http://msdn.microsoft.com/en-us/library/1ffy6686(VS.80).aspx).如果actualLength == Chunksize,这是一个不必要的步骤,因为除了最后一个块之外,它将是所有的.所以我至少建议:
if (actualLength != chunkSize) Array.Resize(ref buffer, actualLength);
Run Code Online (Sandbox Code Playgroud)
这应该删除大量的分配.如果actualSize与chunkSize不同但仍然> 85000,则新数组也将在Large对象堆上分配,可能导致它碎片并可能导致明显的内存泄漏.我相信它仍然需要很长时间才能实际耗尽内存,因为泄漏会很慢.
我认为更好的实现方法是使用某种缓冲池来提供数组.你可以自己动手(这太复杂了)但是WCF确实为你提供了一个.我稍微重写了你的代码,以便采取以下措施:
BufferManager bm = BufferManager.CreateBufferManager(chunkSize * 10, chunkSize);
for (int i = resumeChunk; i < chunks; i++)
{
byte[] buffer = bm.TakeBuffer(chunkSize);
try
{
fileStream.Position = i * chunkSize;
int actualLength = fileStream.Read(buffer, 0, (int)chunkSize);
if (actualLength == 0) break;
//Array.Resize(ref buffer, actualLength);
using (MemoryStream stream = new MemoryStream(buffer))
{
UploadFile(stream, actualLength);
}
}
finally
{
bm.ReturnBuffer(buffer);
}
}
Run Code Online (Sandbox Code Playgroud)
这假设可以重写UploadFile的实现以获取no的int.要写的字节数.
我希望这有帮助
乔
另请参见RecyclableMemoryStream.从这篇文章:
Microsoft.IO.RecyclableMemoryStream是一个MemoryStream替代品,可为性能关键型系统提供卓越的性能.特别是它被优化以执行以下操作:
| 归档时间: |
|
| 查看次数: |
8783 次 |
| 最近记录: |