与CanvasControl相关的奇怪的内存泄漏

时间:2019-10-29 08:38:51

标签: uwp win2d

我设法在一个很小的测试项目中隔离出一个奇怪的问题。所有代码都在下面的代码隐藏中。

主要要点是,如果按下按钮,我将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

0 个答案:

没有答案