Java OutOfMemoryError: Странное поведение - PullRequest
1 голос
/ 30 января 2020

Ниже программа (prog1) выдает ошибку OutOfMemoryError. Справедливо. Но если я добавлю sysout ниже строки 5 (prog2), он не выдаст ошибку. Есть причина такого странного поведения?

prog1:

public static void main(String[] args) {
    List<String> myList = new ArrayList<>();     
    try {
        while (true) {
            myList.add("My String"); //5
            }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

prog2:

public static void main(String[] args) {
    List<String> myList = new ArrayList<>();        
    try {
        while (true) {
            myList.add("My String");
            System.out.println(myList);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

1 Ответ

2 голосов
/ 30 января 2020

Вторая версия также не хватит памяти в конце концов. (Если вам не надоест и вы убьете его первым.)

Проблема в том, что оператор print многократно печатает список, который становится все длиннее и длиннее.

К тому времени, как у вас есть добавили N элементов в список во второй версии, у вас будут напечатаны списки размеров 1 + 2 + 3 + ... + N. Это N * (N + 1) / 2 копии строки "My String" ... и некоторые другие. Это O(N^2).

Если вы пишете это в /dev/null, это займет много времени. Если вы записываете это в файл, дольше. Если вы запишите это на консоль, отображаемую на вашем экране ... вернитесь через несколько часов.


В качестве эксперимента замените

    System.out.println(myList);

на

    System.out.print("X");

Теперь вы будете печатать только O(N) символов вместо O(N^2) ... и OOME произойдет намного раньше.

...