java.lang.OutOfMemoryError:Java堆空间

时间:2011-08-10 15:24:28

标签: java list collections heap out-of-memory

我正在玩一些来自Oracle网站的集合的例子

public class Timing {

    public static void method(){

        List numbers = new ArrayList();

        for (double i = 1; i <= Double.MAX_VALUE; i++)
        numbers.add(new Double(i));

        Collections.shuffle(numbers);
        List winningcombination = numbers.subList(0, 10);
        Collections.sort(winningcombination);
    }

    public static void main(String[] args)
    {
        long start = System.currentTimeMillis();
        method();
        long end = System.currentTimeMillis();
        System.out.println("time elapsed : " + (end-start));
    }
}

我试着看看为Double.MAX_VALUE做多长时间。我得到了这个:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Unknown Source)
    at java.util.Arrays.copyOf(Unknown Source)
    at java.util.ArrayList.ensureCapacity(Unknown Source)
    at java.util.ArrayList.add(Unknown Source)

我有办法解决这个问题吗?

8 个答案:

答案 0 :(得分:17)

有没有办法允许您在Double.MAX_VALUE中创建和存储Collection个对象?没有。地球上没有那么多RAM。 Double.MAX_VALUE大约是第308次幂的2倍:那是2,然后是超过300个零。给Best Buy一个电话,看看他们要把多少钱放在你的电脑里。

答案 1 :(得分:5)

即使您有足够的内存,ArrayList也可以包含最多Integer.MAX_VALUE个元素。 Double.MAX_VALUE远远超过了上限。

在这种情况下,导致数组列表增长的add期间内存不足。

答案 2 :(得分:5)

您的代码无法工作的另一个原因:double只能表示大约2 ^ 52的整数 - 之后,i++将无效,for循环将永远不会终止。

永远不要将浮点变量用作循环计数器。请改用intlong

答案 3 :(得分:2)

您应该只获取10个随机双打,将它们添加到ArrayList并对其进行排序,而不是执行您当前正在执行的操作。这基本上就是你的方法正在做的事情。

要获得随机翻倍,请查看Random.nextDouble()

答案 4 :(得分:1)

您正尝试分配10 ^ 308值的顺序。这是很多价值观。

答案 5 :(得分:0)

增加堆的大小就可以了。只需使用以下参数运行程序:

-Xmx512m

它会将堆大小增加到512 MB。您可以根据需要指定:1g,2g等等。

答案 6 :(得分:0)

for (double i = 1; i <= Integer.MAX_VALUE; i++)
        numbers.add(new Double(i));

答案 7 :(得分:0)

在你循环中:

for (double i = 1; i <= Double.MAX_VALUE; i++)
    numbers.add(new Double(i));

如果有空间,ArrayList只会将值添加到ArrayList。如果不是,它会增加ArrayList的大小,然后继续添加。

所以你基本上做的就是在创建这个ArrayList时使用堆中分配的所有内存。如果你使ArrayList变小,你应该能够将它保存在记忆中。