Почему у JVM больше свободной памяти после моей тестовой программы? - PullRequest
1 голос
/ 07 апреля 2020

Я создал тестовую программу для тестирования метода Runtime.freeMemory ().

public class RuntimeFreeMemory {

    public static void main(String[] args) {
        Runtime r = Runtime.getRuntime();
        System.out.println(r.freeMemory()); // 246939608

        String[] arr = new String[10000000];
        for (int i = 0; i < 10000000; i++)
            arr[i] = new String();

        System.out.println(r.freeMemory()); // 517655928
    }
}

Конечно, это большие числа, но я действительно хотел проверить это, так как числа вроде 10000 не будут сокращаться Это. Но когда я запустил его, я получил несколько неожиданных номеров. Я думал, что конечная свободная память будет go уменьшена или останется такой же, как исходная свободная память, но вместо этого они превысили double , чем была первоначальная свободная память. Я запускал это несколько раз, и это всегда было что-то вокруг этих значений. Может кто-нибудь объяснить это?

1 Ответ

1 голос
/ 07 апреля 2020

На сообщенное freeMemory может повлиять G C и тот факт, что куча была расширена из-за выделений вашего массива. Также может быть интересно напечатать r.totalMemory в начале и в конце и сравнить.

Когда JVM запускается, он фактически не выделяет (по умолчанию) целую кучу памяти заранее - она ​​просто «зарезервирована» "и позже" зафиксировано ", если / когда необходимо (в этот момент куча расширяется).

Вы можете попытаться явно установить -Xms и -Xmx в одно и то же значение и, скорее всего, получите больше ожидаемых результатов .

Например, используя -Xms8g -Xmx8g Я получил следующее:

    public static void main(String[] args) {
        Runtime r = Runtime.getRuntime();
        System.out.println(r.freeMemory()); // 8581851136
        System.out.println(r.totalMemory()); // 8589934592 

        System.out.println("Process PID: " + ProcessHandle.current().pid());

        String[] arr = new String[100000000];
        for (int i = 0; i < 100000000; i++)
            arr[i] = new String();

        System.out.println(r.freeMemory()); // 5717141504
        System.out.println(r.totalMemory()); // 8589934592
    }

    // compare results when using ONLY -Xmx8g
    // 537178112
    // 541065216
    // 3240407040
    // 6104809472

Примечание. Использование -Xms по-прежнему (обычно) не означает, что память находится в ОЗУ: Java кучи Xms и linux свободной памяти разной

...