我设法在一个很小的测试项目中隔离出一个奇怪的问题。所有代码都在下面的代码隐藏中。
主要要点是,如果按下按钮,我将MainGrid内容替换为新的网格,并向该次要的新网格中添加新的CanvasControl,则不会发生内存泄漏。
但是,如果我改为替换一个CanvasInGrid对象,该对象继承了Grid,并将画布添加到它自己的内容中,那么每当我按下按钮时,CanvasInGrid和CanvasControl的对象计数就会增加,如诊断工具/内存使用情况/拍摄快照
但是,如果我在CanvasInGrid中添加按钮而不是,则不会发生内存泄漏。
我只能把它作为CanvasControl中的bug放下吗?还是我错过了什么?以这种方式添加canvas控件时,有没有一种安全的方法来防止此问题?
即使我抓到CanvasInGrid_Unloaded并设置Canvas = none,Canvas的数量似乎也没有增加,但是我得到了包括CanvasInGrid在内的其他一些东西的增加:
IntPtr +1 +12 +12 12 144 144
ConditionalWeakTable +1 +32 +216 12 384 2,592
ConditionalWeakTable + Container +1 +184 +184 12 2,208 2,208
WindowsRuntimeMarshal + NativeOrStaticEventRegistrationImpl + TokenListCount +1 +20 +20 12240240
WindowsRuntimeMarshal + NativeOrStaticEventRegistrationImpl + EventRegistrationTokenListWithCount +1 +24 +24 12 288 288
App1.CanvasInGrid +1 +20 +20 6 120144
Public NotInheritable Class MainPage
Inherits Page
Private sp As New StackPanel
Private MainGrid As New Grid
Public Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Content = sp
Dim b As New Button
b.Content = "test"
AddHandler b.Click, AddressOf test
sp.Children.Add(b)
sp.Children.Add(MainGrid)
Application.Current.DebugSettings.EnableFrameRateCounter = False
End Sub
Private Sub test(sender As Object, e As RoutedEventArgs)
MainGrid.Children.Clear()
'this does NOT cause a leak
'Dim testgr = New Grid
'Dim canv As New CanvasControl
'testgr.Children.Add(canv)
'gr.Children.Add(testgr)
'this DOES cause a leak
MainGrid.Children.Add(New CanvasInGrid)
End Sub
End Class
Public Class CanvasInGrid
Inherits Grid
Public button As Button
Public Canvas As CanvasControl
Public Sub New()
Canvas = New CanvasControl
'button = New Button 'if I do this with a button instead of the Canvas there is no leak
Children.Add(Canvas)
'Children.Add(button)
End Sub
End Class