c# - 我是如何解决这个内存泄漏问题的?

标签 c# .net memory-leaks .net-2.0

我有一个 .net 2.0 应用程序,它执行一些繁重的处理,使用大量内存,并且执行更多操作。它从网络服务中获取任务,完成它的工作,返回结果,然后无限重复所有这些。

主要代码结构可以通过这个来简化和说明

while (true) 
{
     Task t=ServiceAccess.GetTask();
     if (t.TaskType == 1)
     {
          BrutalMemoryConsumerProcessor b=new BrutalMemoryConsumerProcessor();
          b.DoTask(t);
     } 
     else if (t.TaskType == 2)
     {
          HeavyCPUConsumerProcessor h=new HeavyCPUConsumerProcessor();
          h.DoTask(t);
     }
}

对我来说幸运的是,它在内部代码某处出现 OutOfMemoryException 几个循环后就死了。这是因为两个对象都经过校准以使用几乎所有的 RAM(对于 x86 应用程序),并且在创建新对象实例时使用旧对象实例是进程终止的可靠方法。

好的,所以我首先尝试了一些技巧。即:

GC.Collect();

在循环的开始,就在 while (true) 之后。

运气不好。

接下来,我想起了过去基于 VB6 COM 的日子,并在 if 的范围内尝试了 b = null;h = null; > 语句 block 。

又一次不走运。

组合,没有骰子。

启动内存分析器。我有一段时间没有使用它,所以我需要浏览几页“程序文件”才能找到它。是YourKit Profiler .不错的玩具...

无论如何,在对它进行一些干预之后,它告诉我对 bh 的引用保留在本地“堆栈范围”内。所以我做了猴子会做的事情,并将上面的内容重写为:

while (true) 
{
     Task t=ServiceAccess.GetTask();
     if (t.TaskType == 1)
     {
          DoTaskType1(t);
     } 
     else if (t.TaskType == 2)
     {
          DoTaskType2(t);
          HeavyCPUConsumerProcessor h=new HeavyCPUConsumerProcessor();
          h.DoTask(t);
     }
}

private void DoTask1(Task T)
{
    BrutalMemoryConsumerProcessor b=new BrutalMemoryConsumerProcessor();
    b.DoTask(T);
}

private void DoTask2(Task T)
{
    HeavyCPUConsumerProcessor b=new HeavyCPUConsumerProcessor();
    b.DoTask(T);
}

天哪。它解决了内存泄漏问题。

因此,尽管 if 代码块本身就是作用域,但通过将对象创建移动到一个肯定会超出作用域的函数中,对象得到了释放和删除。

为什么?

最佳答案

您可能在未优化的情况下运行(在 Debug模式下,或附加了调试器)。在这种情况下,JIT 将局部变量的生命周期延长到方法的末尾以帮助调试。

使用单独的方法,局部变量只存在于一个单独的堆栈框架中,很快就会消失。

在没有调试器的情况下在 Release模式下尝试。

关于c# - 我是如何解决这个内存泄漏问题的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18595552/

相关文章:

c# - 在使用 C# 和 MySQL 重新启动应用程序之前,不会加载新记录

.net - 对于 .Net 项目,我应该从源代码管理中排除哪些文件扩展名?

.net - BeginPaint 的 hWnd 参数值是否正确?

c# - 我什么时候会在 using 指令上使用别名?

c# - params object[] 方法参数装箱了吗?

c# - 无法递归删除用户文件夹中的文件夹。 'System.UnauthorizedAccessException' 出现在 mscorlib.dll 中

memory-leaks - IE 6 中存在内存泄漏的大型 Web 应用程序

ios - 我会不会漏水

objective-c - SubstringWithRange NSString 内存泄漏

c# - 如何在 C# 中查找名称以某个字符串开头的 HTML 元素的数量?