【问题标题】:1000000000 array input in javajava中的1000000000数组输入
【发布时间】:2015-07-26 20:43:47
【问题描述】:

我正在尝试测试需要 1,000,000,000 个数组输入的算法。

Scanner scanner = new Scanner(new File("999999998.txt"));
int[] tall = new int[1000000000];
int i = 0;
while (scanner.hasNextInt()) {
    tall[i++] = scanner.nextInt();
}

抛出此异常:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

【问题讨论】:

  • 您真的需要一次将所有数字都保存在内存中吗?那是 4 GB...
  • 你的堆小于 4GB(你的数组大小)
  • 是的,我需要用大输入测试我的算法,以便与 else 进行比较。我怎样才能增加堆?
  • 指定你的算法,这将极大地帮助提供超越“如果这个,做A,否则如果那个,做B,......”的更有针对性的解决方案。

标签: java arrays heap-memory


【解决方案1】:

您正在尝试创建一个(大致)4G 数组,但它太大而无法放入堆中(十亿个 4 字节整数)。

如果您想这样做,很可能需要在 64 位操作系统上运行 64 位 Java(并且可能需要大量物理内存以提高性能),并增加堆大小比默认值大得多(例如java -Xmx6g 或类似的东西)。

或者,如果您的算法能够对数据进行分段操作,那可能是更好的选择。

因此,如果您要对文件中的项目求和,则可以一次将它们放入一千个中,以将它们添加到运行总计中。现在,如果对各种不同的整数进行大量随机访问,这并不容易,但在这种情况下,您可以在磁盘上创建数组并使用缓存/LRU 接口来确保只加载所需的内容任何给定的点。

【讨论】:

  • 除了 64 位 JVM 和大堆之外,根据算法的访问模式,它可能还需要 4GB 以上的物理内存。
  • @Patricia,不确定是否需要,操作系统可能可以将大型虚拟地址空间分页到有限的实际地址空间。但是,对于性能而言,这可能是必不可少的,因此我进行了更改。谢谢。
【解决方案2】:

首先,我同意所有建议您尝试保留尽可能少数据的 cmets 和答案。

假设您真的确实需要所有这些数据,您需要使用 -Xmx 标志以更多内存启动您的 java 容器:

java -Xmx6g <your launch args here>

如果您无法使用上述参数启动 Java,那么这意味着您正在运行 32 位 Java 您没有 6GB 可用内存(这意味着在这两种情况下你都不能分配这个大小的数组)。

【讨论】:

  • 谢谢@TimBiegeleisen - 在你修改我的答案的同时! :)
  • 我应该在哪里编写该代码?我试图在 netbeans 上的 VM 选项上写类似的东西,但它不起作用
【解决方案3】:

出于多种原因,我建议不要使用几乎 4GB 的阵列,首先你会吃掉最多的内存资源,如果不是所有的内存资源的话,其次它可能更容易,而且总体上更好地分解它。

尝试将数据分解到不同的文件中,或者只是将文件中的数据逐个读取到数组中并这样处理。

如果您想处理这样的数据,请执行以下操作:

1)。确保您是 64 位操作系统和 64 位 java 版本,否则这是不可能的。

2)。将您的 java 内存堆大小增加到超过 4GB,可能是 5 或 6。使用命令 java -Xmx6g programName 其中 xmx 是命令,6g 是堆大小,programName 是程序的名称。从 Windows 命令提示符运行程序时。或者只是在您的 IDE 中设置。

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-17
    • 1970-01-01
    • 2013-07-21
    • 1970-01-01
    • 2017-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多