简体   繁体   English

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

[英]Memory leak in Blazor Server-side project

I made a simple system to add and delete file from an EF Core database like this :我制作了一个简单的系统来从 EF Core 数据库中添加和删除文件,如下所示:

  • Add a file :添加文件:

     public async Task AddFile(IFileListEntry file) { File fileToAdd = await File.GetFileAsync(file); _context.Files.Add(fileToAdd); _context.SaveChanges(); }
  • Get the file from an IFileListEntry interface, containing the file into a Stream :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; }
  • Remove a file :删除文件:

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

All the files added are stored into a List , and deleted from it, and the list itself is contained into .razor file (not shown here as I think it's irrelavant to my problem), and also in an EF Core database.添加的所有文件都存储到List ,然后从中删除,并且列表本身包含在.razor文件中(此处未显示,因为我认为它与我的问题无关)以及 EF Core 数据库中。

The database context _context is obtained through depedency injection and inherits from DbContext class.数据库上下文_context是通过依赖注入获取的,继承自DbContext类。

So my problem is : after adding and deleting a file, I can observe a memory leak as the RAM is at the same level after the addition of the file into the database and the list.所以我的问题是:添加和删除文件后,我可以观察到内存泄漏,因为在将文件添加到数据库和列表后,RAM 处于同一级别。

So what I'm doing wrong ?那么我做错了什么? I really can't understand where it could possibly come from, as the MemoryStream is disposed after its use, and when the file is deleted, I replace the filled byte[] by an empty one, or even a null reference.我真的不明白它可能来自哪里,因为MemoryStream在它使用后被处理,当文件被删除时,我用空的byte[]替换填充的byte[] ,甚至是null引用。 I made sure the List in my .razor file is a new empty list that we fill up again with the files added.我确定List在我.razor文件是一个新的空单,我们与添加的文件再次填满。 I didn't test for the _context though.不过,我没有测试_context

I think that your DI container does not dispose the dbcontext.我认为您的 DI 容器不会处理 dbcontext。

Check the dbcontext documentation here 在此处查看 dbcontext 文档

The lifetime of the context begins when the instance is created and ends when the instance is either disposed or garbage-collected.上下文的生命周期在创建实例时开始,并在实例被释放或垃圾收集时结束。 Use using if you want all the resources that the context controls to be disposed at the end of the block.如果您希望将上下文控制的所有资源都放在块的末尾,请使用 using。 When you use using, the compiler automatically creates a try/finally block and calls dispose in the finally block.使用 using 时,编译器会自动创建一个 try/finally 块并在 finally 块中调用 dispose 。

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

If the context instance is created by a dependency injection container, it is usually the responsibility of the container to dispose the context.如果上下文实例是由依赖注入容器创建的,那么处理上下文通常是容器的责任。

So if your DI does not dispose the context, then it remains in memory and thus, it looks like you have a leak.因此,如果您的 DI 没有处理上下文,那么它会保留在内存中,因此看起来您有泄漏。

Another thing that may occur, is that the Garbage Collection does not occur predictably check garbage collection here .可能发生的另一件事是垃圾收集不会发生可预测地检查垃圾收集 So it might take some time to see the freed memory.所以可能需要一些时间才能看到释放的内存。

One last thing: You don't need to ms.Dispose();最后一件事:你不需要ms.Dispose(); MemoryStream 内存流

This type implements the IDisposable interface, but does not actually have any resources to dispose.此类型实现 IDisposable 接口,但实际上没有任何资源可供处理。 This means that disposing it by directly calling Dispose() or by using a language construct such as using (in C#) or Using (in Visual Basic) is not necessary.这意味着不需要通过直接调用 Dispose() 或使用诸如 using(在 C# 中)或 Using(在 Visual Basic 中)之类的语言构造来处理它。

So the MemoryStream would not be the problem.所以MemoryStream不会是问题。

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

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