【问题标题】:How to deal with large arrays in Java [closed]如何在 Java 中处理大型数组 [关闭]
【发布时间】:2012-01-05 17:48:00
【问题描述】:

我正在读取一个包含 10,000 个 int 值的文件,然后尝试将它们存储在一个数组中。抛出异常,表示数组值太大。

我想知道,与其将这个数组写到一个变量中,我是否可以将它保存在内存中并从那里读取它。这会是解决这个问题的合适方法吗?

编辑:

经过更多检查,抛出的错误似乎是“代码过大以用于 try 语句”错误。我正在读取每个数组元素并将其附加到一个字符串中,也许这是导致错误的原因?

【问题讨论】:

  • 10000 对于数组来说并不是一个很大的数字,但最好使用列表。
  • 你能提供你的代码和异常吗?
  • 变量只不过是对内存中数据的引用!
  • 变量在内存中,我不确定你想要做出什么区分。您是否尝试过使用 -Xmx 参数增加应用程序可用的内存?
  • “而不是将这个数组写到一个变量中,我可以把它保存在内存中吗?”基本上是一样的。

标签: java arrays memory


【解决方案1】:

包含 10,000 个int 值的数组大约为 40KB。

您可以尝试进一步减少使用的内存,但我怀疑这不是您的问题。

你能告诉我们实际的错误信息吗?数组值只有在 long 时才会太大,例如假设您使用File.length()/4 来确定数组的大小,在这种情况下您需要将其转换为int

【讨论】:

    【解决方案2】:

    您可以改用 ArrayList - 但数组应该可以容纳 10,000 个值。你能发布更详细的信息吗?代码、完整的堆栈跟踪等。理论上,Integer.MAX_VALUE 元素应该没问题(很多超过 10k),但当然你可能首先会耗尽内存!

    就“将其保存在内存中并从那里读取”而言,变量只是保存在内存中,因此无论您使用数组还是列表(或任何其他数据结构),您都会一直在读取它凭记忆!

    编辑:根据您的附加解释,这根本不是数组大小的问题,而是您生成 10,000 行代码放在一个块中的问题,这太多了,因此它会抱怨。更改您的代码以生成使用循环的代码,并且一切都应该很好,无论您在其中有多少元素(当然最多为 Integer.MAX_VALUE。)

    【讨论】:

      【解决方案3】:

      奇怪的是你不能创建 10000 个元素的长数组。我相信您的问题不是数组长度,而是特定数组元素的值。无论如何,如果您需要更大的数组,请改用列表。特别是java.util.LinkedList

      【讨论】:

      • 使用LinkedList而不是数组会增加至少3倍所需的内存我敢打赌:你必须将int包装在java.lang.Integer中,然后你有每个条目的开销由 LinkedList 中的一个对象表示,因此每个值至少有 2 个额外的对象,Java 对象头至少是 ints 的大小(在 64 位平台上更大)。不要介意垃圾收集器必须做的额外工作来处理这么多的对象。这只是没有意义,抱歉投反对票。
      【解决方案4】:

      10,000 个整数的数组根本不是很大。我想不出为什么将数据保存在内存中(即分配给变量)会有问题。

      【讨论】:

        【解决方案5】:

        我觉得奇怪的是 10,000 个整数占用了太多内存。如果吃掉你的记忆,它可能是其他东西。您是否尝试过增加 Java 的可用内存? (即-Xmx512m)。如果这不可能,如果数字足够小,您总是可以尝试使用短裤或字节。

        数组将占用与内存块一样多的空间(就像 c 一样)。

        【讨论】:

          【解决方案6】:

          这是 JVM 中的一个已知错误。它禁止您创建大小为 10,000 的整数数组(在 Mac OS X 上也为 16,384)。它与 Java 将字节码转换为机器码的方式有关。将数组的大小更改为 10,001 即可解决问题。

          【讨论】:

            【解决方案7】:

            您的问题是您正在完整地写出每个数组或字符串分配,如下所示:

                    array[0] = 0;
                    array[1] = 1;
                    array[2] = 2;
                    // all the way up to 9999!
            

            或者这个:

                    String s = "";
                    s += array[0];
                    s += array[1];
                    s += array[2];
                    // all the way up to 9999!
            

            而不是循环。所以你生成more code than Java will allow in a method

            这会导致您描述的编译错误:

            $ javac Test.java
            Test.java:7: code too large for try statement
                    try {
                        ^
            Test.java:4: code too large
                public static void main(String[] args) {
                                   ^
            2 errors
            

            根据 cmets 中的讨论,您所说的产生此编译器错误的代码的行数并不多。有些事情没有意义 - 您报告的错误与您所说的导致它的代码不一致。在这个后期阶段,我强烈建议您发布一些代码和错误,以便其他人可以尝试了解可能导致此问题的原因。

            (此外,您的问题可能不会引起太多关注,因为您已经接受了答案。如果您的问题实际上没有得到回答,您可能需要重新考虑。)

            【讨论】:

            • 是的,这正是我错了,因为我没有按照你的说法写行,我是在循环中做的,据我所知,它会产生同样的问题。现在只需要稍微改变一下。
            • 我猜你的意思是你正在循环生成代码 - 你正在使用脚本中的循环或类似的循环生成 java 源文件。
            • 例如; for(int i = 0; i
            • 不,该代码不会导致您报告的错误。您描述的错误是由于源代码过多,而不是您在循环中迭代了多少次。
            • 抛出它的方法长约 60 行,不包括空格和 catch 语句
            猜你喜欢
            • 1970-01-01
            • 2016-03-25
            • 1970-01-01
            • 2015-11-18
            • 2019-10-17
            • 1970-01-01
            • 2015-12-26
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多