我开发了一个示例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,我会在一段时间后出现内存异常)
答案 0 :(得分:2)
您的代码没有任何问题,您的内存消耗也没有任何问题。无法保证关闭您的表单会立即释放内存;实际上,当需要时,GC会回收内存,这通常不是开发人员期望的时候。
.NET中的垃圾收集会自动触发,以响应内存分配 - 也就是说,当您尝试声明一个不适合堆当前Gen0的对象时,将发生垃圾收集
这里要问的真正问题是:为什么你的内存容量为133MB?它会导致你出问题吗?除非您对收集此内存有特定要求,否则我会说不 GC.Collect()
,并让框架为您解决。
(值得注意的是,手动调用GC.Collect()
通常会对应用程序的长期内存消耗产生否定影响。)