2014-01-14 17 views
0

我在类似如下的代码有内存问题阶:斯卡拉如何循环不保持引用

list.foreach(i => { 
    val a = new A(a) 
    a.doSomething() 
}) 

在我的例子A需要相当多的内存和我有一个项目的大名单迭代。当我这样做时,我会在一段时间后出现OutOfMemoryError。我猜测,对每个新的A实例的引用都会保留,直到foreach终止。所以我的问题是两倍:

(一)我是否正确假设每个新的引用保持到foreach终止?

(B)如果这是可以有人建议迭代列表确保引用到新的实例每次迭代之后被释放的最佳方法呢?

感谢 德

+2

在这种情况下,引用不会持久。你确定它不是一个非常大的对象,或者有大量的分配或其他原因吗?你有没有使用Profiler检查你的代码? *对于我给出scala的功能性,这似乎是合乎逻辑的。*对scala没什么特别的。想象一下一个普通的java while循环,其中你一遍又一遍地调用Callable。一旦你离开每个'call()''''''''''就变成垃圾了。 –

+1

“list”的类型是什么?它是“流”吗? – senia

+0

是的,我做了一个不正确的假设(做了一个U和ME的ASS!),并没有检查我的doSomething()中的行为,这确实是使用太多内存的罪魁祸首。 – user79074

回答

0

我可以用我的机器下面的代码与下面36个工作正常36.任何规模复制此:

class A(x: Int) { 
    val s = "*" * x 
    def doSomething() = {} 
    } 

    (1 to 100).foreach(i => { 
    // System.gc() 
    val MB = 1024 * 1024 
    val size = 36 //30+Random.nextInt(10) 
    println(i + " -> Allocating " + size + " MB") 
    val a = new A(size * MB) 
    a.doSomething() 
    }) 

也许这是因为我的机器上JVM的限制。 System.gc()也没有工作。

+2

调用'System.gc()'是一个建议,不会强制垃圾收集器采取行动。 – wheaties

+0

@wheaties:同意。那就是我的意思。 – tuxdna