java.lang.OutOfMemoryError: пространство кучи Java - PullRequest
1 голос
/ 10 августа 2011

Я играл с некоторыми примерами коллекций с сайта 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 ]

17 голосов
/ 10 августа 2011

Есть ли способ позволить вам создавать и хранить Double.MAX_VALUE объекты в Collection?Нет. На Земле не так много ОЗУ.Double.MAX_VALUE примерно в 2 раза больше десяти до 308-й степени: это 2, за которыми следуют более 300 нулей.Позвоните в Best Buy, посмотрите, сколько они взяли бы, чтобы положить это на ваш компьютер.

5 голосов
/ 10 августа 2011

Еще одна причина, по которой ваш код не может работать: double может представлять только целые числа примерно до 2 ^ 52 - после этого i++ не будет иметь никакого эффекта, и цикл for никогда не прекратится.

Вы никогда не должны использовать переменные с плавающей точкой в ​​качестве счетчиков цикла.Вместо этого используйте int или long.

5 голосов
/ 10 августа 2011

Даже если у вас достаточно памяти, ArrayList может содержать не более Integer.MAX_VALUE элементов.Double.MAX_VALUE намного превышает указанный предел.

В этом случае вам не хватило памяти во время add, из-за которого увеличился список массивов.

2 голосов
/ 10 августа 2011

Вместо того, чтобы делать то, что вы в настоящее время делаете, вы просто должны получить 10 случайных двойных чисел, добавить их в ArrayList и отсортировать его.Это в основном то, что делает ваш метод.

Чтобы получить случайный дубль, посмотрите на Random.nextDouble().

1 голос
/ 10 августа 2011

Вы пытаетесь выделить порядка 10 ^ 308 значений. Это много ценностей.

0 голосов
/ 10 августа 2011

В вашем цикле:

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

ArrayList просто добавит значение к ArrayList, если есть место. Если нет, он увеличит размер ArrayList, а затем продолжит добавление.

Итак, в основном вы используете всю память, выделенную в вашей куче, когда вы создаете ArrayList. Если вы сделаете ваш ArrayList меньше, вы сможете хранить его в памяти.

0 голосов
/ 10 августа 2011
for (double i = 1; i <= Integer.MAX_VALUE; i++)
        numbers.add(new Double(i));
0 голосов
/ 10 августа 2011

Увеличение размера кучи подойдет.Просто запустите программу с этим аргументом:

-Xmx512m

Это увеличит размер вашей кучи до 512 МБ.Вы можете указать столько, сколько хотите: 1 г, 2 г и т. Д.

...