C# 如何使用IDisposable修复内存泄漏
我有一个.net应用程序似乎存在内存泄漏问题。net服务启动时大约有100MB的内存,但在负载下大约有400-500MB。我的大多数类都没有非托管资源,那些已经实现IDisposable的类。所以我的问题是在我的课堂上打IDisposable会有帮助吗 4-500 MB本身并不重要。问题是有8种不同的服务。每个都是使用SharpArch、NServiceBus、Windsor和NHibernate构建的。我的感觉是,其中一个问题是由某种东西引起的。我担心的是,所有服务的总内存大约是4 GB内存中的3.2到3.6 GB。它还没有抛出OfMemory异常,但我想在关口阻止它。我还使用了dotTrace,它给了我一些信息,我只是不知道如何根据这些信息采取行动 更长的回答是:不C# 如何使用IDisposable修复内存泄漏,c#,.net,garbage-collection,C#,.net,Garbage Collection,我有一个.net应用程序似乎存在内存泄漏问题。net服务启动时大约有100MB的内存,但在负载下大约有400-500MB。我的大多数类都没有非托管资源,那些已经实现IDisposable的类。所以我的问题是在我的课堂上打IDisposable会有帮助吗 4-500 MB本身并不重要。问题是有8种不同的服务。每个都是使用SharpArch、NServiceBus、Windsor和NHibernate构建的。我的感觉是,其中一个问题是由某种东西引起的。我担心的是,所有服务的总内存大约是4 GB内存中
我想你已经知道了——如果你不知道,你就不会在需要它的类上“打”IDisposable——IDisposable与GC无关。这里唯一重要的是,如果您在对象上不必要地放置了终结器(~classname)——这将导致它们在获得GC之前备份到单线程终结器队列中,无论它们是否包含非托管资源。如果所有具有非托管资源的类都实现了
IDisposable
,并且被正确地处置(通过使用或try/finally),那么进一步添加IDisposable
实现将不会有任何帮助
第一个问题是,你不知道为什么你在泄漏。托管应用程序通常由于以下原因之一而泄漏
- 我有八个进程,每个进程消耗5亿字节的虚拟地址空间
- 我有40亿字节的内存
- 因此,我将得到一个OutOfMemory异常
- 我有八夸脱冰淇淋
- 冰箱里有九夸脱冰淇淋的空间
- 因此,如果我再吃两夸脱冰淇淋,就会有东西融化
- 在32位系统上,是否有任何进程有使用超过20亿字节虚拟内存的危险?一个进程在win32上只能获得2GB的虚拟内存(不是RAM,记住,虚拟内存与RAM无关:这就是为什么它被称为“虚拟”——它不是可由用户代码寻址的硬件;如果你尝试使用更多,你会得到一个OOM
- 是否有任何进程有可能试图分配一个巨大的虚拟内存块,从而导致没有该大小的连续内存块可用?例如,您是否可能在单个阵列中分配一千万字节的数据?再一次,噢
- 所有进程的工作集(即,出于性能原因*需要在RAM中的进程的虚拟内存页)是否小于可用RAM的数量?如果不是,那么很快你就会被揍,但不会被揍
- 如果RAM开始变短,页面文件是否足够大以处理可能被分页到磁盘的虚拟内存页面
答案是,几乎可以肯定不是。您是否通过分析您的服务来验证您实际上保留了不应该保留的内存
请记住,垃圾收集器在需要释放内存之前不一定会释放内存,因此,它达到400-500mb的分配并不罕见。我所关心的问题是,在[在此插入合理的时间段]使用之后,它会进一步上升并达到1Gb,即使它没有处于任何更高的负载水平。我首先关心的是确保您正在测量相关的内容。“记忆”可以指很多不同的东西。耗尽虚拟内存空间和耗尽RAM之间存在巨大差异。翻动页面文件导致的性能问题与创建过多GC压力导致的性能问题之间存在巨大差异 如果您不了解RAM、虚拟内存、工作集和页面文件之间的关系,那么就从阅读开始,直到您了解所有这些内容。你对这个问题的措辞让我怀疑你相信虚拟内存和RAM是一回事他们当然不是。 我怀疑你正在做的算术是: