0

我开发了一个示例 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。

单击任何按钮时,我有某种要求,会打开一个新窗口作为显示对话框,其中包含一个包含数千条记录的网格,例如:6000 到 1Lakh,在这里我对所选记录进行一些操作(这里内存增加)然后关闭窗户。关闭窗口后,内存没有释放,我明确地要执行语句 GC.Collect()

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

4

1 回答 1

2

您的代码没有问题,您的内存消耗也没有问题。不能保证关闭表单会立即释放内存;确实,GC 会在需要时回收内存,而这通常不是开发人员期望的。

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

这里要问的真正问题是:为什么内存保持在 133MB 有问题?是不是给你带来了麻烦?除非您对收集此内存有特定要求,否则我会说不要 GC.Collect(),让框架为您解决。

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

于 2013-10-29T16:25:38.973 回答