如何使用IDisposable修复内存泄漏我有一个.net应用程序似乎有内存泄漏问题。.net服务以大约100MB的内存启动,但在负载下大约为400-500MB。我的大部分课程都没有非托管资源,并且已经实现了IDisposable。所以我的问题是在我的课堂帮助中输入IDisposable?4-500MB本身并不关心。问题是有8种不同的服务。每个都是使用SharpArch、NServiceBus、Windsor和NHibernate构建的。我的感觉是其中一个中的某些东西导致了问题。我担心的是所有服务的总内存约为3.2到3.6GB的内存。它也不会抛出OutOfMemory异常,但我想在通过时将其关闭。我也在使用dotTrace,它给了我一些信息,我只是不确定如何根据这些信息采取行动我首先关心的是确保你正在衡量相关的东西。“记忆”可以指很多不同的东西。用完虚拟内存空间和用完RAM之间存在巨大差异。损坏页面文件导致的性能问题与产生过多GC压力导致的性能问题之间存在巨大差异。如果您不了解RAM、虚拟内存、工作集和页面文件之间的关系,请先阅读一些内容,直到您了解所有这些内容。你问问题的方式让我怀疑你认为虚拟内存和RAM是同一回事。当然不是。我怀疑你正在做的算术是:这个三段论是完全无效的。这是三段论:事实上,你有一个冷藏设施,其大小相当于隔壁的整个仓库。请记住,RAM只是将物品放在您需要的地方(例如冰箱)附近的一种快速简便的方法。如果您有更多的东西要存储,谁会在乎您是否在本地用完了空间?您可以随时跳出隔壁,将您使用的东西长期深度冻结-页面文件。这不是很方便,但没有任何东西融化。“内存不足”异常发生在进程用完虚拟地址空间时,而不是系统中的所有RAM都被消耗时。当系统中的所有RAM都被消耗时,你不会得到错误,你会得到废话,因为操作系统将所有时间都花在从磁盘来回运行东西上。所以无论如何,首先要了解您要测量的内容以及内存在Windows中的工作原理。您应该查找的内容:到目前为止,这些都与.NET没有任何关系。一旦您真正确定存在真正的问题——而且可能没有——然后开始根据实际问题进行调查。使用内存分析器检查内存分配器和垃圾收集器正在做什么。查看大对象堆中是否有大块,或者无法收集的活动对象的意外大图,或者什么。但应用良好的工程原则:了解系统、使用工具调查实际的经验性能、试验变化并仔细测量其结果。不要只是开始在几个类上随机使用神奇的IDisposable接口,并希望这样做会导致问题(如果有的话)消失。如果所有具有非托管资源的类都实现了IDisposable并得到了正确处理(通过使用或尝试/最终),那么添加更多IDisposable实现将无济于事。第一个问题是你不知道为什么会漏水。托管应用程序通常由于以下原因之一而泄漏:未正确处理非托管资源保留托管对象的大型对象图根据您问题中的信息,#2几乎肯定会导致问题。您需要一个分析器或windbg来告诉您实际泄漏是什么以及是哪些有根对象导致的。这是Rico撰写的一篇很棒的文章,可以帮助您入门答案是,几乎可以肯定不是。您是否通过分析服务确认您实际上正在获取不应该占用的内存?请记住,垃圾收集器不一定会在需要之前释放内存,因此它分配400-500mb的内存可能并不少见。我担心的一件事是,在[插入一段合理的时间]之后,它会进一步攀升并达到1Gb,即使它没有处于任何更高的负载水平。简短的回答:没有。更长的答案:不。我想你已经知道了——如果你不知道,你就不会在需要它的类上“拍打”IDisposable——IDisposable与GC无关。唯一真正重要的是你是否无条件地将终结器(~类名)放在你的对象上——这将导致它们在被GC之前在单线程终结器队列中备份,无论是否它们包含非托管资源或否。测量,测量,测量如果您想减少应用程序的内存使用,您需要首先确定它的使用位置。您可以通过在“私有字节、所有堆中的字节、大对象堆中的字节、第1代、第2代”等上添加一些性能计数器来大致了解。如果您确定使用了太多托管内存。您可以使用.NetMemoryAnalyzer或非常灵活但windbg+sos之类的工具来进一步分解使用情况,一旦您分离了内存的位置,您就可以查看减少使用的策略,这可能就像用Cache替换Dictionary或添加characters就像字符串生成器一样简单。该解决方案不太可能将IDisposable洒在所有东西上。以上是C#学习教程:HowtouseIDisposabletofixthememoryleak。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
