user32和内存泄漏?

时间:2013-05-22 11:36:57

标签: c# memory-leaks pinvoke user32

经过一些阅读后,我发现你在C#中编码的所有东西都是托管代码,不应该给内存泄漏。然而,我的程序表现出某种内存泄漏的方式。

我的整个程序归结为:(目前我没有实际代码)

while(true)
{
    //Source of the "leak"
    List<object> _objects = ReturnAllWindows(); 

    //Do something awesome with the list...

    System.Threading.Thread.Sleep(10);
}

ReturnAllWindows是一种将pinvokeuser32.dllEnumWindows结合使用以获取当前打开的所有窗口的方法。

当我运行程序时,内存会立即浮出水面,直到我得到OutOfMemoryException

从我读到的,我唯一能想到的是EnumWindows函数中存在某种内存泄漏,但我很难想象user32没有完全管理。 /强>

那是怎么回事?我该如何预防/解决它?

<小时/> 修改 解决了这个问题,问题是这个列表后来与一些处理不当的多线程结合使用。如果您评论ReturnAllWindows行,从未达到多线程,则平台调用根本不是问题。

1 个答案:

答案 0 :(得分:1)

如果它是platform invoking(即,从托管代码调用本机的,非托管方法),很可能内存不是以这种或那种方式完全管理的。对此稍加思考。从不编写本机非托管应用程序,旨在支持从托管代码调用。因此,对象作为非托管内存存在,由一些较低级别的系统(如果已开发)或不受控制。因此,从托管代码调用本机方法会执行所谓的boxing,它会创建一个包装本机内存的托管对象。

.NET中存在内存泄漏吗?从技术上讲,没有。不是传统意义上的。但垃圾存在的想法绝对是正确的。处理拳击只会进一步混淆(缺乏一个更好的术语)GC。

我认为在你的盒装数据列表的精彩操作的某个地方应该有一个对象的解引用。例如,如果使用foreach迭代数据集合,并且在每个周期完成后不再需要数据,则应删除对它的所有托管引用。例如,请考虑以下示例:

List<object> foo = new List<object>(); // Imagine this is your list of data

foreach (var item in foo)
{
    // Execute an awesome expression here
}

看似无害,这些表达式永远不会释放内存,因为它总是以某种方式引用。内存优化版本如下:

List<object> foo = new List<object>(); // Imagine this is your list of data

while (foo.Count > 0)
{
    var item = foo[0];

     // Execute an awesome expression here

     item = null;
     foo.RemoveAt(0);
}

请注意,在第二个示例中,如何没有剩余的资源引用,并且现在可以对盒装数据进行收集。现在这可能不是完整的问题,因为.NET中的内存问题通常很难追踪。也许考虑分析您的应用程序以更好地了解您的特定问题。希望这会有所帮助。