我需要在Winform用户控件上托管WPF控件。为此,我使用了ElementHost控件。当我运行Ants Memory分析器时,我知道ElementHost控件中存在大量内存泄漏。请在下面找到附加的保留图表,并帮助我修复Memoryleak。
答案 0 :(得分:1)
看起来像cachedLayoutEventArgs
泄漏的某种已知的WinForms问题。根据我的经验,在Windows窗体中存在某些情况,当处置的控件可以缓存在LayoutEventArgs
中时,它会阻止它被正确收集。有关详细信息,请查看Windows Forms Memory Leak主题。
我建议您在处置控件时明确调用PerformLayout()
方法,包含ElementHost
或跟随recomendation帖子中的WPF element host memory leak。
答案 1 :(得分:0)
我首先要创建你自己的ElementHost,重写dispose,看看你是否能看到那些事件中的任何问题。寻找处理dispose时仍然处于闲置状态的处理程序。您可以取消注册dispose方法中的引用
public class MyElementHost : ElementHost
{
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if(disposing)
{
//Use debugging tools to identify handlers and unregister
MyEventHandler myEventHandler = (MyEventHandler)Delegate.CreateDelegate(typeof(MyEventHandler), this, "childElement_MyLeakingEvent");
FrameworkElement fe = Child as FrameworkElement;
if(fe != null)
fe.MyLeakingEvent -= myEventHandler;
}
}
Child = null;
Parent = null;
}
如果没有任何代码暗示提示,很难说问题出在哪里,但这将是一个不错的起点
答案 2 :(得分:0)
我遇到了完全相同的内存泄漏情况,并且症状完全相同。这是我处理情况的方式。
ElementHost类具有PropertyMap属性,该属性是将WinForms控件属性映射到WPF控件属性的集合。
在这种特殊情况下,内存通过保留MemoryStream实例的BackgroundImage泄漏。 因此,解决方案是删除BackgroundImage属性映射:
elementHost.PropertyMap.Remove("BackgroundImage");
答案 3 :(得分:0)
仅根据Vadim的回答进行扩展。我在TabbedControl上有一个ElementHost
,每次我将其切换回时,都会发生内存泄漏。罪魁祸首BackgroundImage
是罪魁祸首。对于遇到类似困境的人,以下解决方案:
Private Sub BrushesEH_VisibleChanged(sender As Object, e As EventArgs) Handles BrushesEH.VisibleChanged
If BrushesEH.Visible = False Then
BrushesEH.PropertyMap.Remove("BackgroundImage")
GC.Collect()
Else
BrushesEH.PropertyMap.Reset("BackgroundImage")
GC.Collect()
End If
End Sub
GC.Collect
可能过大了吗?不确定。