java - 我应该如何处理 Java 中的一个非常大的数组?

标签 java nio

我有一个算法,目前分配一个非常大的 double 组,它经常更新和搜索。数组的大小为 N^2/2,其中 N 是算法运行的行数。为了与围绕算法的应用程序相关的目的,我还必须保留整个内容的副本。

当然,这对我的算法可以处理的行数施加了限制,因为我要应对堆限制。到目前为止,我已经让使用该算法的人更新 -Xmx 设置以分配更多空间,并且效果很好。但是,我现在遇到了一个真正的问题,我需要这个数组大于我可以放入内存的数组。

我已经计划更改我的算法以减轻这种大型阵列的必要性,并在该领域取得一些有希望的结果。然而,这是对过程的根本改变,需要做更多的工作才能达到我当前代码的高度完善状态,该代码在生产中非常成功地运行并且已经运行了好几年。

因此,在我完善新算法的同时,我想延长现有算法的生命周期,这意味着要解决与分配大量 double 组相关的堆限制。

我的问题是处理它的最佳方法是什么?我应该使用 nio FileChannel 和 MappedByteBuffer,还是有更好的方法。如果我确实使用 nio 方法,与相同大小的内存数组相比,我应该期待什么样的性能下降?

谢谢

最佳答案

如果您开始用完可用内存,那么您可能很快也会用完可用数组索引,数组的大小限制为 Integer.MAX_VALUE,并且当使用 double 作为数组元素的大小“只有”32GB。

获得一台具有 32GB 内存的机器是昂贵的,但可能不如您花时间修改算法和所有相关测试那么昂贵。

但是,如果客户端运行到内存边缘,并且他们的数据集仍在增长,那么您现在咬紧牙关并进行更改以在任何给定时间使用更少的内存是有意义的,因为它们可能很快就会超出数组的容量。

假设数组有些稀疏填充,您还有另一种选择,即使用各种稀疏数组数据结构之一,尽管这些往往仅在数组填充率低于 20% 时才有用。

编辑:既然您似乎已经研究了替代方案,那么 MappedByteBuffer 很可能是可行的方法。显然这会对性能产生影响,但是如果您主要从阵列进行顺序读取和写入,那么这应该不会太糟糕。如果您正在进行随机读写,那么这将变得非常慢非常快。或者非常慢非常慢......取决于你如何看待这些事情;-)

关于java - 我应该如何处理 Java 中的一个非常大的数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1918356/

相关文章:

java - WebSphere 和 PropertyPlaceholderConfigurer

java - 如何在Java 7中使用NIO和JFilechooser?

java - Java 的 FileVisitor.visitFile() 是否可以在不存在的文件上调用?

java - 下载没有缓冲区的文件: Nio is faster than io?

java - ReadableBytechannel.read 始终返回 -1

java - 阻止 Struts 2 验证特定操作

java - 在 JavaFX 中为 Canvas 创建一个 "shadow"层?

java - 使用 servlet 3.1 异步 io 有什么真正的好处?

java - 未知字符

java - 如何使用JOOQ "SELECT SQL_NO_CACHE"?