【问题标题】:How to destroy a usercontrol to free memory?如何销毁用户控件以释放内存?
【发布时间】:2014-05-29 21:11:53
【问题描述】:

我正在开发一个 WPF 应用程序,我有一个方法,我们称之为 GetUIElement(),我的方法返回一个 CustomUserControl,并且我有一个 for 循环我称之为 GetUIElement,问题是当我在 for 循环中有 1000 次迭代时,我的应用程序消耗了太多内存。

PS:

  • 即使我更改 GetUIElement() 签名以返回一个简单的 Button,我也可以看到内存在增长
  • 在CustomUserControl的构造函数和析构函数中我放了一些调试代码来了解我的对象的生命周期,我看到它们在循环之后都被同时销毁,这解释了为什么我的应用程序消耗太多内存,它们都保存在内存中直到循环结束。 我希望我很清楚,如果您需要更多解释,请随时告诉我。 这是代码的一些部分:

    foreach (var item in Data)
    {
    var element = GetUIElement(item);
    
    //...
    }
    
    public FrameworkElement GetUIElement()
    {
        CustomUserControl control = new CustomUserControl();
        control.StartButton.Style = Application.Current.Resources["StandardButton"] as Style;
        return control;
    }
    

【问题讨论】:

  • 显示你的代码......
  • 定义太多内存?
  • @Blam,内存过多我的意思是当应用程序启动时,它会消耗例如 50 MB,并且对于循环的每次迭代,内存量都会增加(我可以看到使用 TaskManager for示例)。
  • 是的,内存会增加。内存起什么作用?什么叫内存过多?
  • 我有 4 GB 的 RAM,在 TaskManager 中我的应用程序消耗了 1.5 GB,我不认为这是正常行为,当我运行我的应用程序时,我无法使用其他任何东西

标签: .net wpf memory-management memory-leaks


【解决方案1】:

为什么您认为您的应用程序消耗了太多内存?

GC 会在需要时收集内存。

如果 GC 一直等到循环结束进行收集,那是因为 GC 已确定它在循环中不需要内存。

如果内存在循环结束时恢复正常,则没有内存泄漏。

任务管理器报告多少内存?

因此,您的应用会消耗 1.5 GB 内存。
GC 可能仍在发挥作用。
它正在收集内存然后它需要。

您的应用正在消耗大量资源,以至于您无法运行其他应用。 这并不意味着 GC 没有完成它的工作。

您丢弃 1000 个用户控件的目的是什么?

你可以这样做,但它不会修复你的程序

foreach (var item in Data)
{
   using (var element = GetUIElement(item))
   {
       //...
   }
   System.GC.Collect();
}

【讨论】:

  • 当我运行应用程序时,总内存为 3.8 GB,我在 Windows 7 上,我的应用程序消耗 1.5 GB
【解决方案2】:

从您所展示的内容来看,这里没有任何问题,GC 不会仅仅因为对象被取消引用而自动启动。如果有问题,您显示的代码不是其中的一部分。

如果您有真正的泄漏,可能是由于创建的控件被存储/引用到其他地方。

【讨论】:

  • 您可以创建一个简单的 WPF 应用程序,在主窗口中添加一个按钮,在按钮的单击事件中放置一个 for 循环,在其中实例化一个用户控件,运行应用程序并观察内存增加(这取决于你的用户控件的大小)
  • 是的,内存会累积,但这并不异常,问题是它是否会获得 GC,我敢打赌它会。
  • 是的,循环后usercontrols被销毁了,问题是循环迭代的时候内存显着增加,不知道有没有办法销毁循环中的usercontrol
  • 所以您不是在任何地方添加这些创建的控件吗?我想查看更多代码,如果您没有将控件添加到任何控件列表中,那么代码的意义何在?
【解决方案3】:

你可以叫垃圾:

System.GC.Collect();

但是,我只想说,如果您真的需要它,您的代码似乎很奇怪...... 您知道可以使用自定义项模板创建 ListBox 吗?

【讨论】:

  • 我尝试了 GC.Collect() 但它不起作用,我没有将控件放在 ListBox 中,我只是在循环中创建用户控件以将它们导出为 .jpg 文件跨度>
  • 你什么时候用的? GC.Collect 将请求垃圾收集器尝试销毁所有未使用的对象。如果您必须将所有 UserControl 存储在 List 中,并且在 List 之后将转换为 jpg。在创建 jpg 之前,您不能销毁您的 UserControl。 GarbageCollector 只会在您的创作结束后销毁它们。您可以创建多个图像而不是一个图像吗?创建“分割图像”后,您可以销毁使用的 UseControls。
猜你喜欢
  • 2019-10-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-07
  • 1970-01-01
  • 1970-01-01
  • 2013-04-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多