【发布时间】:2013-05-17 10:40:28
【问题描述】:
经过阅读后,我发现您在 C# 中编写的所有代码都是托管代码,不应出现内存泄漏。然而,我的程序的行为方式暗示了某种内存泄漏。
我的整个程序归结为:(目前我没有实际代码)
while(true)
{
//Source of the "leak"
List<object> _objects = ReturnAllWindows();
//Do something awesome with the list...
System.Threading.Thread.Sleep(10);
}
ReturnAllWindows 是一种使用pinvoke 结合user32.dll 和EnumWindows 的方法来获取当前打开的所有窗口。
当我运行我的程序时,内存立即飙升,直到我得到一个OutOfMemoryException。
根据我的阅读,我唯一能想到的是EnumWindows 函数中存在某种内存泄漏,但我很难想象 user32 没有得到完全管理。
那么发生了什么?我该如何预防/解决它?
编辑: 解决了它,问题是这个列表后来与一些未正确处理的多线程结合使用。如果您评论
ReturnAllWindows 行,则从未达到多线程,平台调用根本不是问题。
【问题讨论】:
-
你试过打电话给
GC.Collect()吗?看起来很奇怪,你会得到一个OutOfMemoryException,当调用GC.Collect()时会避免异常,但事情就是这样...... -
“您在 C# 中编写的所有代码都是托管代码”:不完全是。您可以使用unsafe 关键字来访问指针。
-
你有 GetWindows() 的代码吗?它是如何分配内存的?如果它使用全局/线程内存来创建列表或创建列表并将其存储在全局/线程变量中,则可能会导致您的列表失控。如果没有 GetWindows() 的代码,将很难诊断。
-
pinvoke 将使您调用非托管代码,当然需要正确处理。并且托管代码不会发生内存泄漏,如果您不小心,很容易造成泄漏,但您不需要为每次分配手动释放资源。
-
@Nolonar 我确实尝试了 GC.Collect(),问题仍然存在。
标签: c# memory-leaks pinvoke user32