Winforms表格永远不会垃圾收集

发布于 2025-01-28 20:54:42 字数 1233 浏览 4 评论 0原文

我有一个温泉表格,并不总是收集的垃圾。该表格加载了很多数据,并且当未收集垃圾时,可能会导致大量内存泄漏。这就是我实例化表单的方式:

// RootForm.cs
private void CreateFormInScope<T>() where T : Form
{
  var scope = _serviceProvider.CreateScope();
  var form = scope.ServiceProvider.GetRequiredService<T>();
  form.FormClosed += (_, _) => scope.Dispose();
  form.MdiParent = this;
  form.Show();
}

在使用Visual Studio的诊断工具无法获得任何地方后,我尝试了dotnet dump。我在一个地址之一上使用了dumpheap -type [typename],然后在其中一个地址上使用了gcroot。这是显示的根的末端:

   - &gt; 00000170022A7598 Microsoft.entityFrameworkcore.infrastructure.coreoptionsextension
 - &gt; 00000170022A1610 microsoft.extensions.dependentienctive.servicelookup.serviceproviderenginescope
 - &gt; 00000170022A2C0 System.Collections.generic.list'1 [[System.Object,System.private.corelib]]
 - &gt; 0000017002BBDD50 System.Object []
 - &gt; 00000170022EF580 functionsCreens.productform
 

好的,范围正在持有对产品形式的引用。唯一可以参考它的范围是我创建的孩子范围,对吗?但是,该儿童范围是一个局部变量,因此不应被任何内容引用,更不用说EF核心了。

如果我在async操作完成之前关闭窗口,则泄漏似乎确实发生了,但是我确实在事件处理程序中捕获了所有例外,以防止它们传播。

有什么想法,为什么它不被gced或我可以做些什么来追踪它?

I have a WinForms Form(s) that is not always garbage collected. The form loads quite a bit of data and when it is not garbage collected, it can cause a significant memory leak. This is how I instantiate the form:

// RootForm.cs
private void CreateFormInScope<T>() where T : Form
{
  var scope = _serviceProvider.CreateScope();
  var form = scope.ServiceProvider.GetRequiredService<T>();
  form.FormClosed += (_, _) => scope.Dispose();
  form.MdiParent = this;
  form.Show();
}

After failing to get anywhere with Visual Studio's diagnostic tools, I tried dotnet dump. I used dumpheap -type [TYPENAME] and then used gcroot on one of the addresses. Here's the end of the root shown:

-> 00000170022A7598 Microsoft.EntityFrameworkCore.Infrastructure.CoreOptionsExtension
-> 00000170022A1610 Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope
-> 00000170022EA2C0 System.Collections.Generic.List`1[[System.Object, System.Private.CoreLib]]
-> 0000017002BBDD50 System.Object[]
-> 00000170022EF580 FunctionScreens.ProductForm

OK, a scope is holding a reference to the ProductForm. The only scope that could have a reference to it is the child scope I created, right? But that child scope was a local variable, so it shouldn't be referenced by anything, let alone EF Core.

The leak does seem to occur more often if I close the window before async operations are complete, but I do catch all the exceptions in the event handlers to prevent them from propagating.

Any ideas why it is not being GCed or what I could do to track it down?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文