Как вы принудительно собираете мусор из Shell?
Итак, я смотрю кучу с jmap на удаленной коробке, и я хочу заставить сбор мусора на ней. Как вы это делаете, не вставляя jvisualvm или jconsole и друзей?
Я знаю, что вы не должны практиковать принуждение к сбору мусора - вам нужно просто понять, почему куча большая/растет.
Я также понимаю, что System.GC() фактически не заставляет сбор мусора - он просто сообщает GC, что вы хотите, чтобы он произошел.
Сказав, что есть способ сделать это легко? Некоторое приложение командной строки мне не хватает?
Ответы
Ответ 1
Вы можете сделать это через бесплатную программу jmxterm.
Запустите его так:
java -jar jmxterm-1.0-alpha-4-uber.jar
Оттуда вы можете подключиться к хосту и запустить GC:
$>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, чтобы сделать это.
UPDATE: здесь один лайнер с использованием jmxterm:
echo run -b java.lang:type=Memory gc | java -jar jmxterm-1.0-alpha-4-uber.jar -n -l host:port
Ответ 2
Начиная с JDK 7 вы можете использовать JDK-команду "jcmd", например:
jcmd <pid> GC.run
Ответ 3
Если вы запустите jmap -histo:live <pid>
, это заставит полный GC в куче, прежде чем он что-либо напечатает.
Ответ 4
Дополнение к 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
Ответ 5
Есть еще несколько решений (здесь уже много хороших):
- Напишите небольшой код для доступа к 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
Это хорошо, потому что это только одна строка, и вы можете легко разместить ее в script.
Ответ 6
Я не думаю, что для этого есть какая-либо опция командной строки.
Вам нужно будет использовать jvisualvm/jconsole для этого.
Я бы предпочел вам использовать эти инструменты для идентификации, почему ваша программа высока в памяти.
В любом случае вы не должны принуждать GC, так как это, безусловно, нарушит алгоритм GC и сделает вашу программу медленной.
Ответ 7
Если вы используете jolokia с вашим приложением, вы можете запустить сборку мусора с помощью этой команды:
curl http://localhost:8558/jolokia/exec/java.lang:type=Memory/gc
Ответ 8
для Linux:
$ jcmd $(pgrep java) GC.run
jcmd
упакован с JDK, $(pgrep java)
получает идентификатор процесса Java
Ответ 9
только
kill -SIGQUIT <PID>