繁体   English   中英

Blazor 服务器端项目中的内存泄漏

[英]Memory leak in Blazor Server-side project

我制作了一个简单的系统来从 EF Core 数据库中添加和删除文件,如下所示:

  • 添加文件:

     public async Task AddFile(IFileListEntry file) { File fileToAdd = await File.GetFileAsync(file); _context.Files.Add(fileToAdd); _context.SaveChanges(); }
  • IFileListEntry接口获取文件,将文件包含到Stream

     public static async Task<File> GetFileAsync(IFileListEntry file) { using MemoryStream ms = new MemoryStream(); await file.Data.CopyToAsync(ms); File f = new File { Name = file.Name, Type = file.Type, Size = file.Size, LastModified = file.LastModified, Data = ms.ToArray(), }; ms.Dispose(); return f; }
  • 删除文件:

     public void DeleteFile(File file) { file.Data = new byte[0]; //Test _context.Files.Remove(file); _context.SaveChanges(); }

添加的所有文件都存储到List ,然后从中删除,并且列表本身包含在.razor文件中(此处未显示,因为我认为它与我的问题无关)以及 EF Core 数据库中。

数据库上下文_context是通过依赖注入获取的,继承自DbContext类。

所以我的问题是:添加和删除文件后,我可以观察到内存泄漏,因为在将文件添加到数据库和列表后,RAM 处于同一级别。

那么我做错了什么? 我真的不明白它可能来自哪里,因为MemoryStream在它使用后被处理,当文件被删除时,我用空的byte[]替换填充的byte[] ,甚至是null引用。 我确定List在我.razor文件是一个新的空单,我们与添加的文件再次填满。 不过,我没有测试_context

我认为您的 DI 容器不会处理 dbcontext。

在此处查看 dbcontext 文档

上下文的生命周期在创建实例时开始,并在实例被释放或垃圾收集时结束。 如果您希望将上下文控制的所有资源都放在块的末尾,请使用 using。 使用 using 时,编译器会自动创建一个 try/finally 块并在 finally 块中调用 dispose 。

public void UseProducts()
{
    using (var context = new ProductContext())
    {     
        // Perform data access using the context
    }
}

如果上下文实例是由依赖注入容器创建的,那么处理上下文通常是容器的责任。

因此,如果您的 DI 没有处理上下文,那么它会保留在内存中,因此看起来您有泄漏。

可能发生的另一件事是垃圾收集不会发生可预测地检查垃圾收集 所以可能需要一些时间才能看到释放的内存。

最后一件事:你不需要ms.Dispose(); 内存流

此类型实现 IDisposable 接口,但实际上没有任何资源可供处理。 这意味着不需要通过直接调用 Dispose() 或使用诸如 using(在 C# 中)或 Using(在 Visual Basic 中)之类的语言构造来处理它。

所以MemoryStream不会是问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM