2015-10-26 48 views
0

我遇到了Java堆空间的问题,我在其中试图将一个数组的连续元素分组以创建用于计算其转置的矩阵。我有很多值的阵列(26726400)中,我尝试有大小29水桶但是当我测试下面的代码,我得到的异常java.lang.OutOfMemoryError: Java heap space在不增加堆空间的情况下避免java.lang.OutOfMemoryError异常?

val arr = new Array[Int](256 * 3600 * 29) 
    arr: Array[Int] = Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,... 
scala> arr.grouped(29).toArray 
java.lang.OutOfMemoryError: Java heap space 

我的目的是转置矩阵。如果我运行sbt -mem 2048,此代码可以工作,但它是另一种执行此任务而不增加堆空间的方法吗?

回答

1

这可能不会节省很多的内存,虽然它比grouped,这确实缓冲区之间的情侣副本内部肯定更有效。

scala> val arr = new Array[Int](256 * 3600 * 29) 
arr: Array[Int] = Array(0, 0, 0,... 

scala> Array.tabulate(256 * 3600, 29)((i,j) => arr(i * 29 + j)) 
res0: Array[Array[Int]] = Array(Array(0, 0, 0,... 

这在我的科学试验中速度明显加快。

您也可以使用1-dim tabulate,分配Array.ofDim(29)Array.copy

0

那么,对于一个JVM实例的默认存储器上的机器具有> 1Gb的RAM是RAM/4。所以,为你的电脑增加更多的内存,你不必将这个参数传递给sbt。

说笑归说笑,你在这里的数据的至少3份。首先是原始的arr实例,然后运行grouped的结果,然后调用toArray的结果。它甚至可能更多,我不确定隐式转换为ArrayOps,通过调用grouped方法(实际上它没有在Array类中定义)需要此方法。

鉴于你的数据的大小和类型,其中一份大约需要101MB的内存,但不包括与存储相关的任何开销。要解决该问题,请减少您制作的副本数量。例如,我不太明白为什么你需要最后的toArray电话。

作为一个侧面说明,如果它不是一门功课,考虑使用一些现有的库矩阵运算,像jBLAS。

+0

我调用'toArray'是因为我需要在2D数组上应用函数'transpose'。 – alifirat

相关问题