简体   繁体   English

使用double数组时内存泄漏

[英]Memory leaks while using array of double

I have a part of code that operates on large arrays of double (containing about 6000 elements at least) and executes several hundred times (usually 800) . 我有一部分代码可以在大型double数组上运行(至少包含大约6000个元素)并执行数百次(通常为800次)。

When I use standard loop, like that: 当我使用标准循环时,像这样:

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

The memory usage rises for about 40MB (from 40MB at the beggining of the loop, to the 80MB at the end). 内存使用量增加约40MB(从循环开始时的40MB到最后的80MB)。

When I force to use the garbage collector to execute at every iteration, the memory usage stays at the level of 40MB (the rise is unsignificant). 当我强制使用垃圾收集器在每次迭代时执行时,内存使用量保持在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()
}

But the execution time is 3 times longer! 但是执行时间要长3倍! (it is crucial) (这很关键)

How can I force the C# to use the same area of memory instead of allocating new ones? 如何强制C#使用相同的内存区域而不是分配新内存? Note: I have the access to the code of someObject class, so if it would be needed, I can change it. 注意:我可以访问someObject类的代码,所以如果需要,我可以更改它。

Why are you allocating a large, empty singleRow only to overwrite it? 为什么要分配一个大的空singleRow只是为了覆盖它? Maybe you should be passing the array in to have its values modified in place. 也许你应该传入数组来修改它的值。 This would allow you to reuse it. 这将允许您重用它。

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

If the method sometimes fills less than 6000 elements, it could simply return the fill count. 如果该方法有时填充少于6000个元素,则它可以简单地返回填充计数。 Alternately, you could use a List<double> , which will allow resizing. 或者,您可以使用List<double> ,这将允许调整大小。

Make singleRow a parameter and pass it in to the call to producesOutput every time... singleRow一个参数,并把它传递到调用producesOutput每次...

Basically your producesOutput method is probably allocating a new array every time, and the re-assignment of singleRow just marks the old memory as available to remove, but doesn't run the GC for performance reasons. 基本上你producesOutput方法每次可能分配一个新的数组,并重新分配singleRow只是标志着旧的内存为可用来去除,但不运行出于性能考虑GC。

You aren't going to like this, but if you have to force GC you're doing something wrong. 你不会喜欢这个,但如果你不得不强迫GC你做错了什么。 Keep in mind that memory may grow until there's pressure to trigger a GC - this is a GOOD thing because it means GC doesn't run until it has to. 请记住,内存可能会增长,直到触发GC的压力 - 这是一件好事,因为这意味着GC必须运行才能运行。

Here's a silly-sounding test, but it might shed some light on what is happening. 这是一个愚蠢的测试,但它可能会揭示正在发生的事情。 Inside FillWithOutput() comment out most of its functionality. 在FillWithOutput()里面注释掉它的大部分功能。 Then run your loop and measure memeory. 然后运行你的循环并测量记忆。 Incrementally un-comment out pieces of it until you see a blip. 逐渐取消它的一部分,直到你看到一个短暂的。 Now your're getting closer to what is causing the 'leak'. 现在你越来越接近导致'泄漏'的原因。

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

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