【发布时间】:2015-01-01 06:19:37
【问题描述】:
我正在尝试在 Java 中使用非常大的方阵,大约为 n = 1e6 或更多。矩阵不是稀疏的,所以我看不到将它们表示为二维数组的方法,这需要 n^2 * sizeof(int) 位内存。显然,我遇到了堆溢出错误,即使添加编译器标志以使用我的机器允许的最大堆也是如此。
为了这个问题,我愿意假设我拥有完美的计算机(无限 RAM 等),但实际上我使用的是具有 16 GB RAM 的 64 位计算机。似乎我的机器只是如此相关,因为我受到 JVM 而不是我的实际硬件的限制(因为 JVM 不能比我的物理机器拥有 更多 内存)。
我理解(并且被引用,例如,这里 Making a very large Java array)Java 数组不能,即使在理论上,也不能大于用于索引的 MAX_INT。
我的问题是:有没有办法从 JVM 堆中哄出额外的内存
我知道,如果有的话,他们可能不会为我提供更多信息。
举例
在 C 语言中,我可以声明静态常量变量并将它们移动到代码的数据部分,这将具有比堆和堆栈更多的空间 (Where are static variables stored (in C/C++)?)。
在 Java 中,即使我将变量复制到“数据”部分,该值也会进入主堆 static allocation in java - heap, stack and permanent generation 这意味着我已经成功地将一个完整字节从堆中移出(耶!)
我的解决方案
我的“解决方案”并不是真正的解决方案。我制作了一个简单的数据结构,它使用 RandomFileAccess io 过程将数组访问替换为对外部文件的读写。它仍然是恒定时间访问,但是我们从 Java 最快的操作之一变成了一个非常非常慢的过程(尽管我们可以一次从文件中提取“缓存”行,这使得该过程非常快)。 更好的想法?
不是我的问题
我不是在问如何使数组超过 java 的最大数组大小。这是不可能的。这些是嵌套数组 - 单个 n 大小的数组很好,其中 n 个会导致问题。
我不是在问这个 How to deal with "java.lang.OutOfMemoryError: Java heap space" error (64MB heap size) 。垃圾收集无关紧要 - 我什至无法制作数组,更不用说担心它何时被删除。
我也不能使用迭代器(我认为),否则这是可能的;像矩阵乘法这样的函数需要能够直接索引
注意:Java 不是对非常大的矩阵进行运算的正确语言。我最好用算盘。但我在这里,这是我无法控制的。
【问题讨论】:
-
能否将计算分布在多个 JVM 中?使用类似 JPPF,here 就是一个例子
-
在运行时分配更多内存行得通吗?
-
你可以
.allocateDirect()一些ByteBuffers,并使用包装类 -
“我们从 Java 最快的操作之一变成了一个非常非常慢的过程” FileChannel.map();然而,与你不同的是,我必须处理
chars,而不是bytes,所以我的用例比你的更复杂。也许你可以看看我所做的并从中构建:github.com/fge/largetext -
@shekhar 谢谢,从长远来看,这似乎是最强大的选择