2010-08-19 10 views
68

Así que estoy buscando un montón con jmap en un cuadro remoto y quiero forzar la recolección de basura en él. ¿Cómo se hace esto sin aparecer en jvisualvm o jconsole y amigos?¿Cómo fuerzas la recolección de basura del Shell?

Sé que no debería estar en la práctica de forzar la recolección de basura; debería averiguar por qué el montón es grande/en crecimiento.

También me doy cuenta de que System.GC() en realidad no fuerza la recolección de basura, simplemente le dice al GC que le gustaría que ocurra.

Habiendo dicho que hay una manera de hacer esto fácilmente? ¿Alguna aplicación de línea de comando que me falta?

+0

* * No es lo mismo que ahora http://stackoverflow.com/questions/1481178/how-to-force-garbage-collection-in-java – Raedwald

Respuesta

20

Puede hacerlo a través del programa gratuito jmxterm.

fuego hacia arriba, así:

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

A partir de ahí, se puede conectar a un GC anfitrión y el gatillo:

$>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 

mirada a los documentos en el sitio jmxterm web para obtener información acerca de incrustar esto en bash/perl/ruby ​​/ otras secuencias de comandos. He usado popen2 en Python o open3 en Perl para hacer esto.

ACTUALIZACIÓN: aquí hay un uso de jmxterm de una sola línea:

echo run -b java.lang:type=Memory gc | java -jar jmxterm-1.0-alpha-4-uber.jar -n -l host:port 
0

No creo que haya ninguna opción de línea de comandos para el mismo.

Deberá usar jvisualvm/jconsole para el mismo.

Le sugiero que utilice estas herramientas para identificar, por qué su programa tiene mucha memoria.

De todos modos no debe forzar GC, ya que sin duda alteraría el algoritmo de GC y haría que su programa fuera lento.

6

Hay algunas otras soluciones (un montón de buenos aquí ya):

  • escribir un poco de código para acceder a la MemoryMBean y llame al gc().
  • Usando una línea de comandos del cliente JMX (como cmdline-jmxclient, jxmterm) y ejecute la operación gc() en el MemoryMBean

El siguiente ejemplo es para el cmdline-jmxclient:

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

Esto es agradable porque es solo una línea y puedes ponerla en una secuencia de comandos muy fácilmente.

88

Si ejecuta jmap -histo:live, eso forzará un GC completo en el montón antes de que se imprima algo.

+5

* * eso es lo que yo' Estoy hablando de eso! – sourcedelica

+2

fuerza una recolección de basura en todos los javas: ps axf | grep java | grep -v grep | awk '{print "jmap -histo: live" $ 1}' | sh – gtrak

+0

¿Dónde está eso documentado? ¿Qué pasa con sin: en vivo (por ejemplo, cuando se necesita -F)? – nafg

-6

simplemente:

kill -SIGQUIT <PID> 
+4

Esto desencadenará un volcado de pila no una recolección de basura –

+0

al menos es solaris hace una fuerza GC. –

+2

Ni siquiera en Solaris, SIGQUIT activará ni un GC ni un volcado de pila. SIGQUIT activará un volcado de hilo solo para HotSpot. Para IBM JVM es configurable. –

221

Desde JDK 7 se puede utilizar la herramienta de comando JDK 'jcmd' tales como:

jcmd <pid> GC.run

+13

¿Por qué la gente no me habla de estas cosas? :) – noahlz

+2

Justo lo que estaba buscando, gracias. –

+8

¿Cómo esta no es la respuesta aceptada? – brunorey

0

Si está utilizando jolokia con su aplicación, puede desencadenar una recolección de basura con este comando:

curl http://localhost:8558/jolokia/exec/java.lang:type=Memory/gc 
0

Además de la respuesta user3198490. La ejecución de este comando que podría dar la siguiente mensaje de error:

$ 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 
... 

Esto se puede solucionar con la ayuda de this stackoverflow answer

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

donde <process_owner> es el usuario que ejecuta el proceso con PID <pid>. Usted puede obtener tanto de top o htop

Cuestiones relacionadas