Как вы заставляете сбор мусора из раковины? - PullRequest
89 голосов
/ 19 августа 2010

Итак, я смотрю на кучу с jmap на удаленном боксе и хочу принудительно собрать на нем сборку мусора. Как это сделать, не заходя в jvisualvm или jconsole и друзей?

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

Я также понимаю, что System.GC () на самом деле не вызывает сборку мусора - он просто сообщает сборщику мусора, что вы хотели бы, чтобы это произошло.

Сказав, что есть способ сделать это легко? Какое приложение командной строки мне не хватает?

Ответы [ 8 ]

296 голосов
/ 15 января 2014

Начиная с JDK 7, вы можете использовать инструмент команды JDK 'jcmd', например:

jcmd <pid> GC.run

98 голосов
/ 19 августа 2010

Если вы запустите jmap -histo:live <pid>, это заставит полный GC в куче, прежде чем он что-либо напечатает.

21 голосов
/ 19 августа 2010

Вы можете сделать это с помощью бесплатной программы jmxterm .

Запустите его так:

java -jar jmxterm-1.0-alpha-4-uber.jar

Оттуда вы можете подключиться к хосту и запустить GC: * ​​1008 *

$>open host:jmxport
#Connection to host:jmxport is opened
$>bean java.lang:type=Memory
#bean is set to java.lang:type=Memory
$>run gc
#calling operation gc of mbean java.lang:type=Memory
#operation returns: 
null
$>quit
#bye

Просмотрите документы на веб-сайте jmxterm для получения информации о внедрении этого в сценарии bash / perl / ruby ​​/ other. Для этого я использовал popen2 в Python или open3 в Perl.

ОБНОВЛЕНИЕ: вот одна строка, использующая jmxterm:

echo run -b java.lang:type=Memory gc | java -jar jmxterm-1.0-alpha-4-uber.jar -n -l host:port
11 голосов
/ 06 февраля 2018

Дополнение к ответу user3198490 .Выполнение этой команды может привести к появлению следующего сообщения об ошибке:

$ jcmd 1805 GC.run    
[16:08:01]
1805:
com.sun.tools.attach.AttachNotSupportedException: Unable to open socket file: target process not responding or HotSpot VM not loaded
...

Это можно решить с помощью ответа на этот стекопоток

sudo -u <process_owner> jcmd <pid> GC.run

, где <process_owner> - этопользователь, который запускает процесс с PID <pid>.Вы можете получить оба из top или htop

6 голосов
/ 19 августа 2010

Есть несколько других решений (здесь уже много хороших):

  • Напишите небольшой код для доступа к MemoryMBean и позвоните gc().
  • Используя клиент командной строки JMX (например, cmdline-jmxclient , jxmterm ) и запустите операцию gc() в MemoryMBean

Следующеепример для cmdline-jmxclient:

$ java -jar cmdline-jmxclient-0.10.3.jar - localhost:3812 'java.lang:type=Memory' gc

Это хорошо, потому что это всего одна строка, и вы можете очень легко поместить ее в скрипт.

0 голосов
/ 22 декабря 2017

Если вы используете jolokia со своим приложением, вы можете запустить сборку мусора с помощью этой команды:

curl http://localhost:8558/jolokia/exec/java.lang:type=Memory/gc
0 голосов
/ 17 января 2013

просто:

kill -SIGQUIT <PID>
0 голосов
/ 19 августа 2010

Я не думаю, что есть какая-либо опция командной строки для того же.

Для этого вам нужно будет использовать jvisualvm / jconsole.

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

В любом случае вам не следует форсировать GC, так как это определенно нарушит алгоритм GC и замедлит вашу программу.

...