C# 什么策略和工具对查找.NET中的内存泄漏有用? 我写C++有10年了。我遇到了内存问题,但只要付出合理的努力就可以解决
在过去的几年里,我一直在写C。我发现我仍然有很多记忆问题。由于不确定性,它们很难诊断和修复,因为C#哲理是,当你非常确定的时候,你不应该担心这些事情 我发现的一个特殊问题是,我必须显式地处理和清理代码中的所有内容。如果我不这样做,那么内存分析器就没有真正的帮助,因为到处都是垃圾,你无法在它们试图显示给你的所有数据中找到漏洞。我不知道我是否有错误的想法,或者我的工具不是最好的 什么样的策略和工具对解决.NET中的内存泄漏有用?当我怀疑内存泄漏时,我会使用Scitech的 到目前为止,我发现它非常可靠和强大。至少有一次它救了我的命C# 什么策略和工具对查找.NET中的内存泄漏有用? 我写C++有10年了。我遇到了内存问题,但只要付出合理的努力就可以解决,c#,.net,memory-management,memory-leaks,C#,.net,Memory Management,Memory Leaks,在过去的几年里,我一直在写C。我发现我仍然有很多记忆问题。由于不确定性,它们很难诊断和修复,因为C#哲理是,当你非常确定的时候,你不应该担心这些事情 我发现的一个特殊问题是,我必须显式地处理和清理代码中的所有内容。如果我不这样做,那么内存分析器就没有真正的帮助,因为到处都是垃圾,你无法在它们试图显示给你的所有数据中找到漏洞。我不知道我是否有错误的想法,或者我的工具不是最好的 什么样的策略和工具对解决.NET中的内存泄漏有用?当我怀疑内存泄漏时,我会使用Scitech的 到目前为止,我发现它非常可
GC在.NET IMO中工作得很好,但就像任何其他语言或平台一样,如果您编写的代码不好,就会发生不好的事情。在编写托管代码时,您仍然需要担心内存问题,除非您的应用程序微不足道。我建议两件事:首先,通过C#阅读CLR,因为它将帮助您理解.NET中的内存管理。其次,学习使用CLRProfiler(微软)等工具。这可以让您了解导致内存泄漏的原因(例如,您可以查看大型对象堆碎片)我们在项目中使用了Red Gate软件。它适用于所有基于.NET语言的应用程序 我们发现.NET垃圾收集器在清理内存中的对象时非常“安全”(应该如此)。它会把物体留在周围,只是因为将来某个时候我们可能会使用它。这意味着我们需要更加小心地考虑我们在内存中膨胀的对象的数量。最后,我们将所有数据对象转换为“按需充气”(就在请求字段之前),以减少内存开销并提高性能 编辑:下面是对我所说的“按需充气”的进一步解释。在数据库的对象模型中,我们使用父对象的属性来公开子对象。例如,如果我们有一些记录引用了其他一些“详细信息”或“查找”记录,我们会这样构造它:
class ParentObject
Private mRelatedObject as New CRelatedObject
public Readonly property RelatedObject() as CRelatedObject
get
mRelatedObject.getWithID(RelatedObjectID)
return mRelatedObject
end get
end property
End class
我们发现,当内存中有大量记录时,上述系统会产生一些实际内存和性能问题。因此,我们切换到一个系统,在这个系统中,对象只有在被请求时才会膨胀,而数据库调用只有在必要时才会进行:
class ParentObject
Private mRelatedObject as CRelatedObject
Public ReadOnly Property RelatedObject() as CRelatedObject
Get
If mRelatedObject is Nothing
mRelatedObject = New CRelatedObject
End If
If mRelatedObject.isEmptyObject
mRelatedObject.getWithID(RelatedObjectID)
End If
return mRelatedObject
end get
end Property
end class
事实证明,这种方法效率更高,因为在需要对象之前,对象一直处于内存之外(Get方法被访问)。它在限制数据库命中率方面提供了极大的性能提升,并极大地增加了内存空间。最好记住的是跟踪对对象的引用。最终很容易挂起对您不再关心的对象的引用。 如果你不打算再使用某些东西,就把它扔掉
习惯于使用具有滑动过期的缓存提供程序,这样,如果某个对象在所需的时间窗口内未被引用,它将被取消引用并清理。但是如果它被大量访问,它会说在内存中。最好的工具之一是使用,并使用adplus对进程进行内存转储,然后使用windbg和sos插件来分析进程内存、线程和调用堆栈 您也可以使用此方法来识别服务器上的问题,在安装工具后,共享目录,然后使用(net use)从服务器连接到共享,并对进程进行崩溃或挂起转储
然后分析脱机。
< P>如果您观察到的泄漏是由于失控的高速缓存实现,这是一个场景,您可能需要考虑使用WeakReference。这有助于确保在必要时释放内存但是,IMPO最好考虑一个定制的解决方案——只有你真正知道需要多长时间来保持对象的周围,所以为你的情况设计合适的内务代码通常是最好的方法。 < P>只是为了忘记处理问题,试试。以下是要点:
public void Dispose ()
{
// Dispose logic here ...
// It's a bad error if someone forgets to call Dispose,
// so in Debug builds, we put a finalizer in to detect
// the error. If Dispose is called, we suppress the
// finalizer.
#if DEBUG
GC.SuppressFinalize(this);
#endif
}
#if DEBUG
~TimedLock()
{
// If this finalizer runs, someone somewhere failed to
// call Dispose, which means we've failed to leave
// a monitor!
System.Diagnostics.Debug.Fail("Undisposed lock");
}
#endif
您正在使用非托管代码吗?根据微软的说法,如果你不使用非托管代码,传统意义上的内存泄漏是不可能的 但是,应用程序使用的内存可能不会被释放,因此应用程序的内存分配可能会在应用程序的整个生命周期中增长 从 .NET中可能会发生内存泄漏 当您使用 非托管代码作为 应用这种非托管代码可以 泄漏内存和.NET Framework 运行时无法解决该问题 此外,项目可能仅限于 似乎有内存泄漏。这 如果许多大的 对象(例如DataTable对象) 声明,然后添加到 集合(例如数据集)。这个 这些对象拥有的资源可能 永远不要释放资源 在整个过程中都是活着的 节目。这似乎是一个错误 泄漏,但实际上它只是一个 记忆方式的症状 在程序中被分配 对于处理此类问题,您可以实现。如果您想了解一些处理内存管理的策略,我建议您搜索IDisposable、XNA和内存管理,因为游戏开发人员需要有更可预测的垃圾收集,因此必须强制GC完成它的工作 一个常见的错误是t