繁体   English   中英

使用double数组时内存泄漏

[英]Memory leaks while using array of double

我有一部分代码可以在大型double数组上运行(至少包含大约6000个元素)并执行数百次(通常为800次)。

当我使用标准循环时,像这样:

double[] singleRow = new double[6000];
int maxI = 800;
for(int i=0; i<maxI; i++)
{
singleRow = someObject.producesOutput();
//...
// do something with singleRow
// ...
}

内存使用量增加约40MB(从循环开始时的40MB到最后的80MB)。

当我强制使用垃圾收集器在每次迭代时执行时,内存使用量保持在40MB的水平(上升是无关紧要的)。

double[] singleRow = new double[6000];
int maxI = 800;
for(int i=0; i<maxI; i++)
{
singleRow = someObject.producesOutput();
//...
// do something with singleRow
// ...
GC.Collect()
}

但是执行时间要长3倍! (这很关键)

如何强制C#使用相同的内存区域而不是分配新内存? 注意:我可以访问someObject类的代码,所以如果需要,我可以更改它。

为什么要分配一个大的空singleRow只是为了覆盖它? 也许你应该传入数组来修改它的值。 这将允许您重用它。

double[] singleRow = new double[6000];
int maxI = 800;
for(int i=0; i<maxI; i++)
{
    someObject.FillWithOutput(singleRow);
    //...
    // do something with singleRow
    // ...
}

如果该方法有时填充少于6000个元素,则它可以简单地返回填充计数。 或者,您可以使用List<double> ,这将允许调整大小。

singleRow一个参数,并把它传递到调用producesOutput每次...

基本上你producesOutput方法每次可能分配一个新的数组,并重新分配singleRow只是标志着旧的内存为可用来去除,但不运行出于性能考虑GC。

你不会喜欢这个,但如果你不得不强迫GC你做错了什么。 请记住,内存可能会增长,直到触发GC的压力 - 这是一件好事,因为这意味着GC必须运行才能运行。

这是一个愚蠢的测试,但它可能会揭示正在发生的事情。 在FillWithOutput()里面注释掉它的大部分功能。 然后运行你的循环并测量记忆。 逐渐取消它的一部分,直到你看到一个短暂的。 现在你越来越接近导致'泄漏'的原因。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM