Заставить JVM освободить память - PullRequest
0 голосов
/ 19 января 2019

Я улучшил свой код, чтобы получить лучший результат от сборщика мусора.

Теперь, когда я звоню System.gc(), это освобождает всю память. Но когда я наблюдаю за использованием памяти без вызова System.gc(), приложение резервирует и использует все больше и больше памяти.

Означает ли это, что мои улучшения работают, и я правильно понял все ссылки, и я могу игнорировать, как JVM сама освобождает память. Или в моем коде есть другие проблемы, из-за которых JVM резервирует больше памяти без запуска сборщика мусора.

Ответы [ 4 ]

0 голосов
/ 19 января 2019

Конечно, существует вероятность утечки памяти, то есть ваша программа продолжает выделять память, даже не освобождая ее.(Например, в постоянно растущем списке или на карте.) Вам потребуется профилировщик памяти, чтобы убедиться, что вы не страдаете от такой ситуации.

Кроме этого, я не буду беспокоиться, есливиртуальная машина продолжает выделять память, не освобождая ее.Так работают современные виртуальные машины, особенно в «клиентском» режиме: до тех пор, пока имеется много свободной памяти, они не будут тратить время на сборку мусора.Если предел памяти приближается, то тогда включается сборщик мусора.(Режим «клиент» и «сервер» - это аргумент JVM, с ним можно поэкспериментировать, если хотите, подробнее здесь: Реальные различия между "java -server" и "java -client"? )

Кроме этого, вы можете сделать следующее:

a) убедиться, что ваш механизм выполнения полного GC фактически выполняет полный GC.Лучший известный мне механизм (который не гарантированно сработает, но, насколько я могу судить, работает) - это выделить объект, на который ссылаются только через мягкую ссылку, и затем продолжать вызывать GC, пока мягкая ссылка не станет нулевой..

b) при выполнении отладки (скажем, если утверждения включены) продолжайте запуск полного GC в отдельном потоке каждые несколько секунд.Затем, если вы посмотрите на память, потребляемую виртуальной машиной, она должна оставаться примерно постоянной.Если нет, то у вас утечка памяти.

0 голосов
/ 19 января 2019

Зависит от того, какой GC использует ваша JVM. Если это JDK9, то это, вероятно, G1, который «жадный», когда дело доходит до потребления памяти, поэтому в зависимости от того, каким образом вы проверяете используемую память, может показаться, что она занимает много памяти (где это резервирует ее и использует / освобождает динамически / по требованию.

Вы можете использовать

https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.html

для проверки потребления памяти.

А что касается анализа потребления памяти и памяти, проверьте следующее: Проблемы с высоким использованием памяти в сборщике мусора G1 + https://www.javacodegeeks.com/2017/11/minimize-java-memory-usage-right-garbage-collector.html

0 голосов
/ 19 января 2019

Неиспользуемая память - это потерянная память.

Почему вы хотите явно вызвать System.gc().ИМХО, вы никогда не должны вызывать его и оставлять на усмотрение JVM решать, когда запускать GC.(JVM может принимать лучшие решения, чем вы, если вы новичок. Звоните System.gc() только тогда, когда вы действительно знаете, что делаете.) Как правило, плохая практика - звонить System.gc().

System.gc() - это просто запрос / подсказка JVM для запуска GC.Это никоим образом не означает, что GC будет работать точно.

У вас могут быть утечки памяти в Java, но это точно не то, на что нужно обратить внимание в вашем случае, потому что, как вы упоминали, когда вызываете System.gc(), выможно увидеть освобождение памяти.(Так что это не тот случай, когда вы все еще держите ссылку на неиспользуемые объекты, что может помешать GC очистить эти объекты.)

Почему вы думаете, что это проблема с вашим кодом?Может случиться так, что больше не требуется никакой дополнительной памяти или если требуется дополнительная память, у вас ее уже достаточно (и, говоря языком мирян, GC не освобождает память, так как для выполнения программы еще много места -так зачем GC беспокоиться об очистке памяти?).

0 голосов
/ 19 января 2019

Невозможно заставить JVM освободить память, System.gc() - это просто подсказка.Управление памятью зависит от GC (обратите внимание, что существуют различные типы памяти, например, куча, метапространство, внеплановая память).Каждый алгоритм GC имеет несколько параметров конфигурации, которые вы можете настроить, но ни один из них не даст вам возможности освободить память по требованию.

JVM резервирует память при запуске и запрашивает дополнительную память у ОС до тех пор, пока она не достигнет любых пределов.сконфигурировано.Он делает это с шагом по частям, запрашивая МБ или больше памяти за раз, потому что запрос памяти из байта ОС будет очень неэффективным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...