user32 和内存泄漏? [关闭]

Posted

技术标签:

【中文标题】user32 和内存泄漏? [关闭]【英文标题】:user32 and memory leak? [closed] 【发布时间】: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.dllEnumWindows 的方法来获取当前打开的所有窗口。

当我运行我的程序时,内存立即飙升,直到我得到一个OutOfMemoryException

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

那么发生了什么?我该如何预防/解决它?


编辑: 解决了它,问题是这个列表后来与一些未正确处理的多线程结合使用。如果您评论ReturnAllWindows 行,则从未达到多线程,平台调用根本不是问题。

【问题讨论】:

你试过打电话给GC.Collect()吗?看起来很奇怪,你会得到一个OutOfMemoryException,当调用GC.Collect() 时会避免异常,但事情就是这样...... “您在 C# 中编写的所有代码都是托管代码”:不完全是。您可以使用unsafe 关键字来访问指针。 你有 GetWindows() 的代码吗?它是如何分配内存的?如果它使用全局/线程内存来创建列表或创建列表并将其存储在全局/线程变量中,则可能会导致您的列表失控。如果没有 GetWindows() 的代码,将很难诊断。 pinvoke 将使您调用非托管代码,当然需要正确处理。并且托管代码不会发生内存泄漏,如果您不小心,很容易造成泄漏,但您不需要为每次分配手动释放资源。 @Nolonar 我确实尝试了 GC.Collect(),问题仍然存在。 【参考方案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 中的内存问题通常很难追踪。也许考虑分析您的应用程序以更好地了解您的特定问题。希望这会有所帮助。

【讨论】:

以上是关于user32 和内存泄漏? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

它是C中的内存泄漏吗?

当我在 FuelPHP 中循环创建模型时内存泄漏

内存分析和搜索内存泄漏[关闭]

javascript中的关闭和回调内存泄漏

Android ValueAnimator --内存泄漏

Python内存泄漏[关闭]