Почему Java-сборщик мусора OpenJDK 11 * уменьшает * объем свободной памяти в этом примере программы? - PullRequest
7 голосов
/ 16 марта 2019

Когда я компилирую и запускаю следующую очень простую Java-программу с использованием OpenJDK 11 (дистрибутив Zulu в Windows 10):

public class GCTest {
    public static void main(String[] args) {
        System.out.println("Free memory before garbage collection: " + Runtime.getRuntime().freeMemory());
        Runtime.getRuntime().gc();
        System.out.println("Free memory  after garbage collection: " + Runtime.getRuntime().freeMemory());
    }
}

похоже, что сборка мусора уменьшение количество свободной памяти:

Free memory before garbage collection: 266881496
Free memory  after garbage collection: 7772200

Этого не происходит, когда я запускаю его с Oracle 8:

Free memory before garbage collection: 254741016
Free memory  after garbage collection: 255795064

Почему это?

Ответы [ 2 ]

10 голосов
/ 16 марта 2019

Ответ: GC Java 11 (при явном вызове, например, через System.gc()) может уменьшить используемую память процесса Java (в Java, известной как totalMemory).

В Java 8 сборщик мусора по умолчанию не смог уменьшить объем используемой памяти процесса Java.Память, занятая процессом Java, никогда не освобождалась.Только если вы переключаетесь на сборщик мусора G1GC (опция '-XX:+UseG1GC'), Java 8 может уменьшить используемую память процесса Java (если вы вручную вызываете System.gc()).

«Свободная память»"является памятью, занятой процессом Java, но которая в настоящее время не используется.Поэтому, если вы выполняете сборку мусора и память, занимаемая Java, уменьшается, объем свободной памяти также уменьшается.

Поэтому наиболее распространенным способом вычисления «свободной памяти» процесса Java является использование

Runtime r = Runtime.getRuntime();
long free = r.maxMemory() - r.totalMemory() + r.freeMemory();

Этот способ не зависит от текущей памяти, занимаемой процессом Java.

2 голосов
/ 16 марта 2019

Я думаю, что вы видите, что JDK решает, что ваша куча слишком велика для нужд вашего приложения, и возвращает ее в операционную систему, тем самым уменьшая размер кучи Java и, как побочный эффект, также свободное / неиспользуемоекуча памяти.

...