我有一个MDI,其中有一个子表单。子表单中包含DataGridView。我在datagrid视图中加载了大量数据。当我关闭子窗体时,调用处理方法,我在其中处理datagridview
this.dataGrid.Dispose();
this.dataGrid = null;
当我关闭表格时,内存不会下降。我使用.NET memory profiler来跟踪内存使用情况。我看到当我最初加载数据网格时(如预期的那样)内存使用量很高,然后在加载完成时变为常量。
当我关闭表格时,它仍然保持不变。但是,当我使用内存分析器拍摄内存快照时,它会降低到加载文件之前的状态。获取内存快照会导致它强行运行垃圾收集器。
发生了什么事?有内存泄漏吗?或者我是否需要强行运行垃圾收集器?
更多信息:
当我关闭表单时,我不再需要这些信息。这就是我没有提到数据的原因。
更新
我需要一次加载所有数据。当有大量数据时,内存使用率非常高,所以我想知道我是否做错了什么并且垃圾收集器没有运行但另一方面当我查看分析器时它确实显示当它需要时快照内存使用量减少。所以我无法理解发生了什么。
答案 0 :(得分:6)
将变量设置为null
并不会神奇地强制调用垃圾收集器。 GC'是一个昂贵的过程,除非绝对必要,否则应该避免使用,因此收集器只能按计划运行或在需要时运行。
如果确实需要确保释放内存,请在清空DataGrid后手动调用垃圾收集器:
this.dataGrid.Dispose();
this.dataGrid = null;
GC.Collect();
然而,正如Matthew Scharley指出的那样,如果CLR保留在那个记忆中真的重要吗?如果你强制它被释放,那么下次你的DataGrid被填充时,CLR需要重新分配相同数量的内存 - 这很慢。
除非您的DataGrid消耗接近或超过计算机上的物理内存,否则请单独使用CLR - 在内存管理方面,它几乎肯定是最清楚的。
答案 1 :(得分:5)
这很正常。垃圾收集器根据需要在它自己的时间运行。当垃圾收集器被强制它恢复正常的事实意味着没有泄漏或永久引用保持周围。
真正的问题是:垃圾收集器是否需要运行?你使用的RAM是否超过你的物理范围?如果没有,如果您使用的是一堆没有其他需要的物理RAM,那么真的是否重要?
另一个非常好的问题是,您是否真的需要立即将所有数据加载到您的应用程序中?但如果没有更多信息,就无法回答这个问题。
答案 2 :(得分:2)
垃圾收集不会因为您使引用为空而发生。如果您不再引用对象,则会在某个时刻收集它。仅仅因为它仍然存在一段时间并不意味着你有内存泄漏。此外,即使您进行垃圾收集,内存也不一定会立即释放到操作系统,因此您可能看不到应用程序的内存使用量下降。
答案 3 :(得分:-1)
GC.WaitForPendingFinalizers();
- 这帮助了我。
答案 4 :(得分:-2)
这是一个用于跟踪内存泄漏的有用工具: