我正在使用WinForms中的C#应用程序,并且面临内存泄漏问题。
当用户单击按钮时,将调用一个方法,其中正在创建新变量。 它们可以在RAM中捕获50M-100M(有时它是文件处理,但它也适用于所有其他类型的变量)。
现在,问题是,在方法完成后,内存仍然保持在50M-100M,看起来好像它们(变量)没有被破坏(我看着任务管理器使用的内存)
如果我在方法中创建它们,那么当方法结束时GC不应该销毁它们吗? 如果它确实破坏了它们,为什么它仍然显示高内存使用?
或者可能是因为按钮点击事件调用了该方法的事实? 如果重要的话,我也在VS调试器中运行该程序。
那么,我应该怎么做才能避免这种情况?变量是100%不是全局变量,因此不是这类问题。
答案 0 :(得分:3)
如果我在方法中创建它们,那么当方法结束时GC不应该销毁它们吗?
没有。此时,对象可能有资格进行垃圾回收,但退出方法不会触发收集。当分配需要GC或系统内存不足时,GC会被触发。
此处的另一个问题是任务管理器报告进程内存。 .NET运行时代表托管应用程序分配和释放内存,并尝试了解如何完成此操作。因此,运行时通常不会在不再需要它们时释放段来支持托管堆。这样做的结果是您的应用程序可以减少其托管内存使用量,而不会立即反映在进程内存中。
答案 1 :(得分:0)
您应该检查的第一件事是您是否正在使用任何实现IDisposable的对象。如果是这种情况,那么请确保在离开其范围之前将其丢弃。
您应该尝试的另一件事是调用GC.Collect并查看是否从内存中删除了对象。如果是这种情况,那么你没有内存泄漏,垃圾收集只是在删除对象之前等了一会儿。
如果这些都没有解决您的问题,那么您仍然必须引用方法中创建的对象。您是否创建了一些在方法结束后仍然存在的对象,这些对象可能引用了您认为是GC的对象?
答案 2 :(得分:0)
在结束方法后,它们不一定会被垃圾收集。 .NET垃圾收集器的正常行为是不确定,也就是说,它不会在精确确定的时间运行,因此您永远无法确定何时将释放内存。
完成一个方法之后,所有变量都超出了范围,并假设正如你所说的那样,没有更多的全局引用保留给那些对象,它们不是符合条件的被收集,但它并不意味着他们会立即。 GC将在后台运行,通常在空闲时间运行,但同样,我们永远无法确定它何时会回收内存。看到这种行为是完全正常的。
如果内存问题真的很紧迫,您可以尝试通过调用GC.Collect
方法强制立即进行垃圾回收。