Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在.NET这样的托管环境中是否可能发生内存泄漏? 在C++中,很容易有永久内存泄漏——只分配内存,不释放它: new char; //permanent memory leak guaranteed_C#_.net_Memory Management_Memory Leaks - Fatal编程技术网

C# 在.NET这样的托管环境中是否可能发生内存泄漏? 在C++中,很容易有永久内存泄漏——只分配内存,不释放它: new char; //permanent memory leak guaranteed

C# 在.NET这样的托管环境中是否可能发生内存泄漏? 在C++中,很容易有永久内存泄漏——只分配内存,不释放它: new char; //permanent memory leak guaranteed,c#,.net,memory-management,memory-leaks,C#,.net,Memory Management,Memory Leaks,并且该内存在堆的生存期内保持分配状态(通常与程序运行时持续时间相同) 在C#程序中是否也存在同样的情况(这种情况会导致在内存管理机制正常工作时,某个特定的未引用对象从未被释放) 我已经仔细阅读并回答了它,它提到了一些导致内存消耗高于预期的情况,或者一些极端情况,比如死锁终结器线程,但是在正常运行内存管理的C#程序中是否会形成永久性泄漏 如果我们将内存泄漏定义为可用于创建对象的内存无法使用或可释放的内存无法使用的情况 内存泄漏可能发生在: WPF中需要使用弱事件的事件。这尤其可能发生在附加属性中

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

在C#程序中是否也存在同样的情况(这种情况会导致在内存管理机制正常工作时,某个特定的未引用对象从未被释放)


我已经仔细阅读并回答了它,它提到了一些导致内存消耗高于预期的情况,或者一些极端情况,比如死锁终结器线程,但是在正常运行内存管理的C#程序中是否会形成永久性泄漏

如果我们将内存泄漏定义为可用于创建对象的内存无法使用或可释放的内存无法使用的情况

内存泄漏可能发生在:

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


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

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

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

最容易的内存泄漏:

public static class StaticStuff
{
    public static event Action SomeStaticEvent;
}

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

侦听器的实例将永远不会被收集。

这并不完全是内存泄漏,但如果您直接与硬件驱动程序通信(即,不是通过一组驱动程序的正确编写的.net扩展),则很可能会将硬件置于以下状态:,虽然您的代码中可能存在内存泄漏,也可能没有内存泄漏,但如果不重新启动硬件或电脑,您将无法再访问硬件


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

如果愿意,您可以在.NET中编写非托管代码,您已经用不安全的关键字将代码块括起来,因此,如果您正在编写不安全的代码,您是否回到了自己管理内存的问题上?如果没有,是否会出现内存泄漏?

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

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

但是,您可以得到另一种“较弱”形式的泄漏:当内存引用确实存在时(因此仍然可以找到并重置该引用,从而允许GC正常释放内存),但您认为它不存在,因此,您假设被引用的对象将被GC’ed。这很容易导致内存消耗的无限增长,因为您正在堆积对不再使用的对象的引用,但这些对象无法被垃圾收集,因为它们仍然在应用程序中的某个位置被引用


因此,在.NET中通常被视为内存泄漏的只是一种情况,即您忘记了对某个对象的引用(例如,因为您未能取消订阅某个事件)。但是引用是存在的,如果您记得它,您可以清除它,泄漏就会消失。

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

根据GC算法的不同,不可访问内存会在收集周期运行时立即被检测到,或者在一定数量的收集周期内未被检测到(例如,分代GC会显示此行为)。有些技术甚至有从未收集过的盲点(例如使用引用计数指针)——有些技术拒绝使用GC算法的名称,它们可能不适合于一般用途的上下文


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

我一直相信GC可以检测循环引用,这就是它相对于智能指针的巨大优势。我也有这样的印象。考虑到一个(旧的)循环引用没有根,GC会将其拾取。实际上,GC很好地处理循环引用,并且不会导致内存泄漏。-1表示不正确。这3个点中没有一个对应于任何类型的内存“泄漏”@spender:是的,但是看着内存使用量表上下跳动很有趣。我是一个简单的人,有着简单的乐趣。:D
内存泄漏是指程序内存使用量无限增长的任何情况
这是错误的。问题不在于泄漏是否有界。
泄漏是指可以释放的内存没有限制不会被释放。
我有一个水龙头,每次使用它都会漏水。那么它是否会漏水?@Aliostad:但你的水龙头只要使用它就会一直漏水。所以它是无限的。不管怎样,你使用的是“m”的不同定义