Donc, je regarde un tas avec jmap sur une boîte distante et je veux forcer le ramassage des ordures dessus. Comment faites-vous cela sans tomber dans jvisualvm ou jconsole and friends?
Je sais que vous ne devriez pas forcer la récupération des ordures - vous devez juste comprendre pourquoi le tas est gros/en croissance.
Je réalise également que System.GC () ne force pas la récupération de place, il indique simplement au GC que vous souhaitez que cela se produise.
Cela dit, y a-t-il un moyen de le faire facilement? Une application en ligne de commande me manque?
Vous pouvez le faire via le programme gratuit jmxterm .
Allumez-le comme ça:
Java -jar jmxterm-1.0-alpha-4-uber.jar
À partir de là, vous pouvez vous connecter à un hôte et déclencher le 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
Consultez la documentation sur le site Web de jmxterm pour plus d'informations sur l'intégration de cela dans bash/Perl/Ruby/d'autres scripts. Pour ce faire, j'ai utilisé popen2 en Python ou open3 en Perl.
UPDATE: voici un one-liner utilisant jmxterm:
echo run -b Java.lang:type=Memory gc | Java -jar jmxterm-1.0-alpha-4-uber.jar -n -l Host:port
Depuis JDK 7, vous pouvez utiliser l'outil de commande JDK 'jcmd' tel que:
jcmd <pid> GC.run
Si vous exécutez jmap -histo:live <pid>
, cela forcera un GC complet sur le tas avant qu'il n'imprime quoi que ce soit.
Ajout à la réponse de user3198490 . L'exécution de cette commande peut vous donner le message d'erreur suivant:
$ 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
...
Ceci peut être résolu avec l'aide de cette réponse stackoverflow
Sudo -u <process_owner> jcmd <pid> GC.run
où <process_owner>
est l'utilisateur qui exécute le processus avec le PID <pid>
. Vous pouvez obtenir les deux à partir de top
ou htop
Il y a quelques autres solutions (beaucoup de bonnes ici déjà):
gc()
.gc()
sur le MemoryMBeanL'exemple suivant concerne le cmdline-jmxclient:
$ Java -jar cmdline-jmxclient-0.10.3.jar - localhost:3812 'Java.lang:type=Memory' gc
C'est bien parce que ce n'est qu'une ligne et que vous pouvez le mettre très facilement dans un script.
Je ne pense pas qu'il existe une option de ligne de commande pour les mêmes.
Vous devrez utiliser jvisualvm/jconsole pour la même chose.
Je vous suggérerais plutôt d’utiliser ces outils pour identifier, pourquoi votre programme a beaucoup de mémoire.
Quoi qu'il en soit, vous ne devriez pas forcer GC, cela perturberait certainement son algorithme et ralentirait votre programme.
Si vous utilisez jolokia avec votre application, vous pouvez déclencher un garbage collection avec cette commande:
curl http://localhost:8558/jolokia/exec/Java.lang:type=Memory/gc