2012-03-02 12 views
9

Duplicar posible:
Forcing Garbage Collection in Java?¿Puedo forzar la recolección de basura en Java?

puedo forzar recolección de basura en Java, por cualquier medio?

System.gc() es solo una sugerencia. Es inútil.

Cuando sé con certeza que algunos recursos ya no se usarán más, ¿por qué no puedo obligarlos a limpiarlos?

Al igual que eliminar() en C++ y libre() en C?

Cuando hay muchos recursos que no se pueden reutilizar, esto realmente puede absorber el rendimiento. Todo lo que podemos hacer es dormir().

Cualquier solución? Gracias

Respuesta

12

No, System.gc() es lo más cerca que se puede conseguir. Java no es C o C++, la JVM administra la memoria para usted, por lo que no tiene ese tipo de control fino. Si configura objetos que ya no usa para anular, o pierde todas las referencias, se limpiarán. Y el GC es bastante inteligente, por lo que debería cuidarte bien.

Dicho esto, si está en una caja de Unix y fuerza un volcado de hilo (matar -3), va a forzar la recolección de basura.

+4

+1 para "The GC is smart." (Es muy inteligente, y rara vez es la verdadera causa de los cuellos de botella de rendimiento). –

+0

@Michael ¿Qué tiene la caja de Unix y forzar un volcado de hilo? ¿Cómo puede esto garantizar la recolección de basura? – Geek

+1

@Geek: cada vez que JVM realiza un volcado de hilo, se pausa para una recolección de basura. Lo hará en cualquier sistema operativo para ser honesto, es más fácil de hacer en Unix/Linux debido a la disponibilidad de 'matar'. Si está en Windows con cygwin, creo que puede lograr lo mismo. – Michael

1

No hay forma de indicar explícitamente a la JVM que recoja la basura. Esto solo se realiza cuando el sistema necesita los recursos.

Las únicas dos acciones yo sepa potencialmente para obtener la GC en ejecución son los siguientes:

  1. Como se ha dicho, intento de "sugieren" que GC ahora sería un buen momento por el denominado Sistema. gc().
  2. Establezca las referencias que no utilice en la referencia nula para que los elementos sean aptos para la recopilación.

En mi segundo punto, consulte la respuesta aquí: Garbage collector in java - set an object null. En esencia, si no hace que los objetos que no necesita estén disponibles para la recolección de basura (al perder la referencia que tiene) entonces no hay ninguna razón para que se ejecute el recolector de basura, ya que no tiene conocimiento de ninguna basura disponible.

Además, es importante tener en cuenta qué/cómo esos objetos en la memoria están afectando el rendimiento:

  • ¿Está recibiendo una gran cantidad de OutOfMemoryExceptions? Esto podría resolverse mediante el punto n. ° 2 y aumentando el espacio de almacenamiento dinámico disponible para la JVM.
  • ¿Ha realizado mediciones para ver que más objetos en el espacio de montón asignado de la JVM hace una diferencia en el rendimiento? Determinar cuándo podría dejar que las referencias a los objetos vayan antes podría ayudar a reducir estos problemas.
5

Usted no debe estar tratando de forzar GC - si está ejecutando bajo en memoria entonces usted tiene una pérdida de memoria en alguna parte. Forzar el GC en ese punto no ayudará, porque si mantiene una referencia al objeto, entonces no será basura.

Lo que tienes que hacer es resolver el problema real y asegurarte de que no tienes referencias a objetos que ya no usas.

Algunos culpables más comunes:

  • sostiene la gran cantidad de referencias en un gran gráfico de objetos que nunca se aclaró. Establezca referencias a null cuando ya no las necesite, o mejor aún, simplifique su gráfico de objetos para que no necesite todas las referencias extra a largo plazo.
  • Almacenamiento en memoria caché de objetos en un hashmap o algo similar que crece enormemente con el tiempo. Deja de hacer esto o usa algo como el CacheBuilder de Google para crear un caché de referencia suave adecuado.
  • Utilizando String.intern() excesivamente en grandes cantidades de cadenas diferentes a lo largo del tiempo.
  • Referencias con mayor alcance de lo que necesitan. ¿Estás usando una variable de instancia cuando podría ser una variable local, por ejemplo?
+0

Buenas sugerencias.Lo intentaré.Gracias – Jacob

+1

Hay razones para forzar un GC. Obviamente, si está a punto de ingresar una pieza de código sensible a la latencia que interactúa con el mundo real, y le gustaría minimizar la posibilidad de que el GC haga una pausa para una colección "grande". Por supuesto, si la latencia es realmente importante, es poco probable que Java sea el mejor lenguaje para el problema, pero a veces estás en un lugar donde ese tipo de error no se puede deshacer. –

+0

Acabo de depurar una aplicación cuando la memoria creció sin control, sin causa aparente, y se agotó rápidamente de 150 GB. Agregar System.gc() en lugares estratégicos lo arregló y lo mantuvo por debajo de 35 GB. La aplicación es intensiva en memoria y altamente paralela. GC no es una solución mágica y está optimizado para casos de uso típicos. A veces es necesario indicar gc() incluso cuando todas las referencias están liberadas o fuera del alcance. – morfizm

Cuestiones relacionadas