内存未发布WPF

时间:2013-10-29 16:19:33

标签: wpf vb.net memory-leaks

我开发了一个示例WPF应用程序,它有一个带一个按钮的窗口 打开应用程序时,如果从任务管理器中观察到,占用的内存:12.3 MB

Dim b As Boolean = False
Private lst As List(Of String)
Private Sub Btn_Close(sender As Object, e As RoutedEventArgs)
    If b = False Then
        If lst Is Nothing Then lst = New List(Of String)
        For i As Integer = 0 To 30
            lst.Add(Convert.ToBase64String(IO.File.ReadAllBytes("d:\test.txt"))) 'memory increases, test.txt file is a 2MB file
        Next
        'do some operations with lst object
        'memory occupied: 133MB
        'now again click the same button, it will go to else case now (cause of the last statement)
    Else
        lst.Clear()
        If MsgBox("GC.Collect()?", MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
            GC.Collect()
            'in this case, memory occupied: 13MB
        Else
            'in this case, memory occupied: 133MB, not cleared
        End If
    End If
    b = Not b
End Sub

仅在执行GC.Collect()语句时才释放内存,否则内存仅保留在133MB。

我在点击任何按钮时都有要求,新窗口打开为showdialog,其中包含一个包含数千个记录的网格,比如:6000到1Lakh,这里我用选定的记录做一些操作(这里内存增加)然后关闭窗口。关闭窗口后,内存未释放,我明确地必须执行语句GC.Collect()

代码中有什么问题吗?或者为什么我需要显式调用GC.Collect,因为CLR会自动处理它? (在我的申请中,如果我在上面重复并且不使用GC.Collect,我会在一段时间后出现内存异常)

1 个答案:

答案 0 :(得分:2)

您的代码没有任何问题,您的内存消耗也没有任何问题。无法保证关闭您的表单会立即释放内存;实际上,当需要时,GC会回收内存,这通常不是开发人员期望的时候。

.NET中的垃圾收集会自动触发,以响应内存分配 - 也就是说,当您尝试声明一个不适合堆当前Gen0的对象时,将发生垃圾收集

这里要问的真正问题是:为什么你的内存容量为133MB?它会导致你出问题吗?除非您对收集此内存有特定要求,否则我会说 GC.Collect(),并让框架为您解决。

(值得注意的是,手动调用GC.Collect()通常会对应用程序的长期内存消耗产生否定影响。)