在.NET等托管环境中是否可能发生内存泄漏?

在C ++中,很容易产生永久性内存泄漏 – 只需分配内存而不释放内存:

new char; //permanent memory leak guaranteed 

并且该内存在堆的生命周期内保持分配(通常与程序运行时持续时间相同)。

在C#程序中是否可以(在内存管理机制正常工作的情况下导致特定的未引用对象的情况相同)?

我仔细阅读了这个问题并给出了答案,它提到了一些导致内存消耗高于预期的情况或IMO相当极端的情况,比如终结器线程死锁,但是在C#程序中可能会发生永久性泄漏而且function正常内存管理?

这取决于您如何定义内存泄漏。 在非托管语言中,我们通常将内存泄漏视为已分配内存的情况,并且不存在对它的引用,因此我们无法释放它。

在.NET中创建这种泄漏几乎是不可能的(除非你调用非托管代码,或者除非运行时有错误)。

但是,您可以获得另一种“弱”forms的泄漏:当存在对内存的引用时(因此仍然可以找到并重置引用,允许GC正常释放内存),但您认为它没有’ t,所以你假设被引用的对象将得到GC。 这很容易导致内存消耗的无限增长,因为你正在堆积对不再使用的对象的引用,但是它们不能被垃圾收集,因为它们仍然在应用程序的某处被引用。

因此,通常认为.NET中的内存泄漏只是您忘记了对对象的引用(例如,因为您未能取消订阅事件)的情况。 但是参考存在,如果你记得它,你可以清除它,泄漏将消失。

如果你愿意,你可以在.NET中编写非托管代码,你用不安全的关键字包含你的代码块,所以如果你正在编写不安全的代码,你是不是要回到自己管理内存的问题,如果没有内存泄漏?

这不是一个内存泄漏,但如果你直接与硬件驱动程序通信(即不通过一组驱动程序的正确编写的.net扩展),那么很可能将硬件置于一个状态,尽管可能或者可能不是代码中的实际内存泄漏,您无法再重新启动硬件或PC而无法访问硬件…

不确定这是否是对你的问题有用的答案,但我觉得值得一提。

当对引用的分析显示内存不可达时,GC通常会将无法访问的内存的收集延迟到以后的某个时间。 (在某些受限制的情况下,编译器可以帮助GC并警告它在内存区域变为无法访问时。)

根据GC算法,一旦运行收集周期就会检测到无法访问的内存,或者在一定数量的收集周期内它可能无法检测到(例如,代GC会显示此行为)。 有些技术甚至有从未收集的盲点(例如使用引用计数指针) – 有些人否认它们是GC算法的名称,它们可能不适用于通用上下文。

certificate将回收特定区域取决于算法和内存分配模式。 对于像标记和扫描这样的简单算法,很容易给出一个约束(直到下一个收集周期),对于更复杂的算法,问题更复杂(在使用动态数代的方案下,条件是完全收集对于不熟悉算法细节和使用的精确启发式的人没有意义

一个简单的答案是经典的内存泄漏在GC环境中是不可能的,因为传统的内存泄漏是泄漏的,因为作为一个未引用的块,软件无法找到它来清理它。

另一方面,内存泄漏是程序的内存使用量无限增长的任何情况。 在分析软件作为服务运行时可能会失败的情况时(定义服务运行,可能一次持续数月),此定义非常有用。

因此,任何可持续保留对不需要的对象的引用的可扩展数据结构都可能导致服务软件由于地址空间耗尽而有效地失败。

最简单的内存泄漏:

 public static class StaticStuff { public static event Action SomeStaticEvent; } public class Listener { public Listener() { StaticStuff.SomeStaticEvent+=DoSomething; } void DoSomething() {} } 

永远不会收集监听器的实例。

如果我们将内存泄漏定义为可以用于创建对象的内存,不能使用的内存或者可以释放的内存那么

内存泄漏可能发生在:

  • WPF中需要使用弱事件的事件。 这尤其可以在附加属性中发生。
  • 大物件

大对象堆碎片

http://msdn.microsoft.com/en-us/magazine/cc534993.aspx