【发布时间】:2015-11-08 03:17:18
【问题描述】:
我正在调查用户上传文件的项目中可能存在的内存泄漏问题。这些文件通常是用于其他软件的 .zip 或 .exe 压缩文件。文件的平均大小为 80MB
有一个 MVC 应用程序具有上传文件的接口(视图)。此视图向控制器中的操作发送 POST 请求。此控制器操作使用类似于此的 MultipartFormDataContent 获取文件:Sending binary data along with a REST API request 和此:WEB API FILE UPLOAD, SINGLE OR MULTIPLE FILES
在操作中,我获取文件并将其转换为字节数组。转换后,我使用 byte[] 数组向我的 API 发送一个发布请求。
这是执行此操作的 MVC APP 代码:
[HttpPost]
public async Task<ActionResult> Create(ReaderCreateViewModel model)
{
HttpPostedFileBase file = Request.Files["Upload"];
string fileName = file.FileName;
using (var client = new HttpClient())
{
using (var content = new MultipartFormDataContent())
{
using (var binaryReader = new BinaryReader(file.InputStream))
{
model.File = binaryReader.ReadBytes(file.ContentLength);
}
var fileContent = new ByteArrayContent(model.File);
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = file.FileName
};
content.Add(fileContent);
var requestUri = "http://localhost:52970/api/upload";
HttpResponseMessage response = client.PostAsync(requestUri, content).Result;
if (response.IsSuccessStatusCode)
{
return RedirectToAction("Index");
}
}
}
return View("Index", model);
}
在调查了使用以下几种内存工具后:Best Practices No. 5: Detecting .NET application memory leaks 我发现在此行将文件转换为字节数组后:
using (var binaryReader = new BinaryReader(file.InputStream))
{
model.File = binaryReader.ReadBytes(file.ContentLength);
}
内存使用量从 70MB + 或 - 增加到 175mb + 或 - 并且即使在发送并完成请求之后,内存也不会被释放。如果我继续上传文件,内存只会不断增加,直到服务器完全关闭。
我们无法将文件直接从多部分表单发送到 API,因为我们需要在之前发送和验证一些数据(业务需求/规则)。经过研究,我采用了这种方法,但内存泄漏问题与我有关。
我错过了什么吗?垃圾收集器应该立即收集内存吗?在所有一次性物品中,我都使用“使用”语法,但它没有帮助。
我也很好奇这种上传文件的方法。我应该以不同的方式做事吗?
为了澄清,API 与 MVC 应用程序是分开的(每个都托管在 IIS 中的单独网站上),并且全部使用 C#。
【问题讨论】:
标签: c# asp.net-mvc file-upload asp.net-web-api memory-leaks