Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.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#大字节数组和内存泄漏(如果不快速为空)_C# - Fatal编程技术网

C#大字节数组和内存泄漏(如果不快速为空)

C#大字节数组和内存泄漏(如果不快速为空),c#,C#,我有一个类,它的字节数组从1048576字节到134217728字节。 在dispose void中,我将数组设置为null,然后调用dispose的方法调用GC.Collect 如果我立即处理,我将收回内存,但如果我等待10个小时并进行处理,内存使用率不会改变。内存使用率取决于操作系统内存分配。它可能会立即被释放,也可能不会。这取决于操作系统的利用率、应用程序等。您可以在运行时释放它,但这并不意味着操作系统总是可以收回它。我不得不认为,这是一个基于记忆模式(即这里的时间)的决定,它会影响何时返

我有一个类,它的字节数组从1048576字节到134217728字节。 在dispose void中,我将数组设置为null,然后调用dispose的方法调用GC.Collect


如果我立即处理,我将收回内存,但如果我等待10个小时并进行处理,内存使用率不会改变。

内存使用率取决于操作系统内存分配。它可能会立即被释放,也可能不会。这取决于操作系统的利用率、应用程序等。您可以在运行时释放它,但这并不意味着操作系统总是可以收回它。我不得不认为,这是一个基于记忆模式(即这里的时间)的决定,它会影响何时返回或不返回的计算。这是在这里提出的:


注意:如果内存未释放,则不会自动表示已使用。这取决于CLR是否释放内存,但这些内存不会被浪费

也就是说,如果您想要一个技术解释,您需要阅读关于大型对象堆的相关文献:

基本上,它是一个内存区域,其中分配了非常大的对象(超过85kB)。它与其他内存区域的不同之处在于它从未被压缩,因此可能变得支离破碎。我认为你的情况是:

  • 案例1:分配对象并立即调用GC.Collect。对象在堆的末尾分配,然后释放。CLR在堆的末尾看到一个空闲段,并将其释放到操作系统

  • 案例2:分配对象并等待一段时间。同时,在LOH中分配另一个对象。现在,你的对象不再是最后一个了。然后,当您调用GC.Collect时,您的对象被擦除,但在内存段的末尾仍然有其他对象。因此CLR无法将内存释放到操作系统


根据我对.NET内存管理的了解,我只是猜测一下。我可能完全错了。

你的发现并不罕见,但这并不意味着任何事情都是错的。为了收集,必须有一些东西提示GC收集(通常是尝试分配)。因此,您可以构建一个消耗大量内存的应用程序,然后将其释放,然后进入空闲状态。如果机器上没有内存压力,并且你的应用程序在这之后没有尝试做任何事情,GC将不会启动(因为它不需要启动)。一旦您忙碌起来,GC就会开始工作。这种行为通常被误认为是泄漏

顺便说一句: 您是否不止一次地使用这个非常大的阵列?如果是这样的话,你最好把它放在身边,然后再利用它。原因:任何大于85000字节的对象都在大型对象堆上分配。该堆仅在第2代集合上获得GC。因此,如果您经常分配和重新分配阵列,将导致大量第2代(昂贵)集合


(注意:这并不意味着总是有一个硬性的规则来重用大型阵列,但是如果您对阵列进行了大量的分配/解除分配/分配,那么您应该衡量重新使用时它有多大帮助)。

到目前为止还不错。你的问题是什么?我不明白为什么时间会导致记忆无法释放。如果有解决问题的方法。@jasonbay13:当内存使用那么长时间时,它会在垃圾收集的几代中得到提升。在以后的世代中,在系统需要它之前,它往往不会被收集,本质上它不是泄漏。您是否尝试过
GC.Collect
上的
Force
选项并指定要收集的代数?@jasonbay13:p.s.我不建议强制使用GC,让GC自己做吧。您占用内存的时间很长,因此GC假定您将继续这样做,并且检查它的频率要低得多。查看世代垃圾收集以了解更多详细信息。您尚未解释这是一个问题的原因。内存没有立即释放。好吧,那谁在乎呢?它将在需要释放时被释放。让垃圾收集器完成它的工作。实际上,我创建了包含不同大小数组的类实例,并且可以随机处理任何一个。我明白了。如果您想真正测试是否发生了泄漏,您可以输入一些测试代码,这些代码可以无限期地创建和释放这些数组。他们最终会离开。可能发生的情况是系统没有足够的压力来推动第2代收集。或者,正如Adam Tuliper所说,数组正在被释放,但内存不会立即返回到O/S。无论哪种方式,只要您没有在某个地方持有对数组的引用,就可能不是真正的泄漏。