我正在调查一个用户上传文件时可能存在的内存泄漏问题。这些文件通常是用于其他软件的.zip或.exe压缩文件,平均大小为80MB。
有一个MVC应用程序具有上传文件(视图)的界面。此视图向控制器中的操作发送POST请求。此控制器操作使用类似于此在REST API请求中发送二进制数据和此WEB API文件上传,单个或多个文件的MultipartFormDataContent获取文件。
在操作中,我获取文件并将其转换为字节数组。转换后,我使用字节数组向我的API发送POST请求。
这里是MVC应用程序执行此操作的代码:
内存使用量从大约70MB +增加到175MB +,即使在发送和完成请求后,内存也永远不会被释放。如果我继续上传文件,内存就会持续增加,直到服务器完全崩溃。
我们无法直接从多部分表单向API发送文件,因为我们需要在发送和验证一些数据之前(业务要求/规则)进行。经过研究,我已经提出了这种方法,但内存泄漏问题令我担忧。
我是否遗漏了什么?垃圾收集器应该立即回收内存吗?在所有可处理的对象中,我都使用“using”语法,但这并没有帮助。
我还对这种上传文件的方法很好奇。我应该采用不同的方式吗?
仅供澄清,API与MVC应用程序分离(每个应用程序在IIS中托管在一个单独的网站上),并且全部使用C#。
有一个MVC应用程序具有上传文件(视图)的界面。此视图向控制器中的操作发送POST请求。此控制器操作使用类似于此在REST API请求中发送二进制数据和此WEB API文件上传,单个或多个文件的MultipartFormDataContent获取文件。
在操作中,我获取文件并将其转换为字节数组。转换后,我使用字节数组向我的API发送POST请求。
这里是MVC应用程序执行此操作的代码:
[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);
}
在研究了多种内存工具后,例如:最佳实践5:检测.NET应用程序的内存泄漏,我发现问题出现在将文件转换为字节数组的这一行代码:
using (var binaryReader = new BinaryReader(file.InputStream))
{
model.File = binaryReader.ReadBytes(file.ContentLength);
}
内存使用量从大约70MB +增加到175MB +,即使在发送和完成请求后,内存也永远不会被释放。如果我继续上传文件,内存就会持续增加,直到服务器完全崩溃。
我们无法直接从多部分表单向API发送文件,因为我们需要在发送和验证一些数据之前(业务要求/规则)进行。经过研究,我已经提出了这种方法,但内存泄漏问题令我担忧。
我是否遗漏了什么?垃圾收集器应该立即回收内存吗?在所有可处理的对象中,我都使用“using”语法,但这并没有帮助。
我还对这种上传文件的方法很好奇。我应该采用不同的方式吗?
仅供澄清,API与MVC应用程序分离(每个应用程序在IIS中托管在一个单独的网站上),并且全部使用C#。