下载期间 ASP.net 内存使用情况
在我工作地点的 ASP.net 站点上,以下代码块负责处理文件下载(注意:此处未使用 Response.TransmitFile,因为下载的内容是从 zip 文件流式传输):
private void DownloadFile( Stream stream)
{
int bytesRead;
int chunkSize = 1048576; //1MB
byte[] readBuffer = new byte[chunkSize];
while ((bytesRead = stream.Read(readBuffer, 0, readBuffer.Length)) != 0)
{
if(!Response.IsClientConnected)
break;
byte[] chunk = new byte[bytesRead];
Array.Copy(readBuffer,0,chunk,0,bytesRead);
Response.BinaryWrite(chunk);
Response.Flush();
}
stream.Close();
}
我们的用户经常下载数百MB的文件,这会很快消耗服务器内存。我的假设是这是由于响应缓冲造成的。这有道理吗?
我刚刚读到了 Response 对象的“buffer”属性。如果我将其设置为 false,是否会阻止 Response.BinaryWrite() 调用在内存中缓冲数据?一般来说,在这种情况下限制内存使用的好方法是什么?也许我应该从 zip 流式传输到临时文件,然后调用 Response.TransmitFile()?
编辑:除了可能的解决方案之外,我对上面代码中存在的内存使用问题的解释非常感兴趣。即使每次循环迭代都会调用 Response.Flush,为什么这会消耗远远超过 1MB 的空间?是否只是每次循环迭代时发生不必要的堆分配(并且不会立即进行 GC),还是还有其他原因在起作用?
On an ASP.net site at my place of work, the following chunk of code is responsible for handling file downloads (NOTE: Response.TransmitFile is not used here because the contents of the download are being streamed from a zip file):
private void DownloadFile( Stream stream)
{
int bytesRead;
int chunkSize = 1048576; //1MB
byte[] readBuffer = new byte[chunkSize];
while ((bytesRead = stream.Read(readBuffer, 0, readBuffer.Length)) != 0)
{
if(!Response.IsClientConnected)
break;
byte[] chunk = new byte[bytesRead];
Array.Copy(readBuffer,0,chunk,0,bytesRead);
Response.BinaryWrite(chunk);
Response.Flush();
}
stream.Close();
}
Our users frequently download multi-hundred MB files, which can chew up server memory pretty fast. My assumption is that this is due to response buffering. Does that make sense?
I've just read about the 'buffer' property of the Response object. If I set that to false, will that prevent the Response.BinaryWrite() calls from buffering the data in memory? In general, what is a good way to limit memory usage in this situation? Perhaps I should stream from the zip to a temporary file, then call Response.TransmitFile()?
EDIT: In addition to possible solutions, I'm very interested in explanations of the memory usage issue present in the code above. Why would this consume far more than 1MB, even though Response.Flush is called on every loop iteration? Is it just the unnecessary heap allocation that occurs on every loop iteration (and doesn't get GC'd right away), or is there something else at work?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是我正在为此编写的一些代码。它使用 8000 字节缓冲区来分块发送文件。对大文件的一些非正式测试显示分配的内存显着减少。
编辑以修复语法错误和缺失值
Here is some code that I am working on for this. It uses an 8000 byte buffer to send the file in chunks. Some informal testing on a large file showed a significant decrease in memory allocated.
edited to fix a syntax error and a missing value