2011-11-11 9 views
5

? He monitorizado mi aplicación Java con Profiler para conocer la pérdida de memoria. Y tengo clase que teniendo casi el 80% de la memoria que es¿Cómo puedo aumentar la prioridad de FinalizerThread para recopilar objetos en GC

java.lang.ref.Finalizer 

Entonces google para la clase anterior y encontré gran artículo http://www.fasterj.com/articles/finalizer1.shtml

Ahora cualquiera puede sugerir cómo puedo aumentar la prioridad de FinalizerThread a recoger esos objetos en GC.

Una cosa más estoy frente a este problema en Linux con la versión del núcleo Linux 2.6.9-5.ELsmp (i386) y Linux 2.6.18-194.17.4.el5 (i386) pero que está funcionando bien (sin error OOM) en Linux 2.6.18-128.el5PAE (i386).

¿Este problema se debe a Linux Kernels? ¿Hay alguna variable JVM para mejorar la prioridad de FinalizerThread?

Gracias por adelantado.

+1

Buena pregunta, creo que en general se necesita minimizar el uso de Finalizer. –

+0

Quizás en modo PAE simplemente tenga más memoria disponible (no PAE está limitado a 4 GB) - marque 'free'. No creo que la versión del núcleo esté en juego aquí. –

+0

Gracias Dan, como Peter sugiere a continuación, ahora estoy comprobando con el sistema de archivos. – user1041580

Respuesta

2

Para responder la pregunta, literalmente puede hacerlo. Sin embargo, como se describe a continuación, es probable que no tenga sentido, especialmente porque el subproceso ya tiene una alta prioridad.

for(Thread t: Thread.getAllStackTraces().keySet()) 
    if (t.getName().equals("Finalizer")) { 
     System.out.println(t); 
     t.setPriority(Thread.MAX_PRIORITY); 
     System.out.println(t); 
    } 

impresiones

Thread[Finalizer,8,system] 
Thread[Finalizer,10,system] 

menos que esté utilizando el 100% de todos sus núcleos, o cerca de ella, la prioridad no importa porque incluso la más baja prioridad será obtener la mayor cantidad de CPU como quiera.

Nota: En Linux, ignorará las prioridades aumentadas a menos que sea root.

En su lugar, debe reducir el trabajo que está haciendo el finalizador. Idealmente, no debería tener nada que hacer. Una causa de alta carga en el finalizador es la creación de recursos que deberían cerrarse pero que se están descartando. (dejando en su lugar el finalizador para cerrar el recurso)

En resumen, debe intentar determinar qué recursos se están finalizando y asegurarse de que no necesitan hacer nada cuando se invoca finalize(), idealmente no use este método en absoluto.

Es posible que los recursos tarden un poco más en cerrarse en la versión anterior del kernel de Linux. Verificaría que el hardware sea idéntico ya que esto podría significar que lleva más tiempo limpiar el recurso. (Pero la verdadera solución es asegurarse de que no necesita hacer esto)

+0

Es java puede hacer la diferencia. Debido a que First two Linux (donde surge el problema OOM), estoy usando 64 bit Java y uno donde funciona bien, estoy usando 32 bit? – user1041580

+0

La versión de Java, ya sea que esté utilizando 64 bits o 32 bits, qué hardware está usando CPU, memoria, disco, ancho de banda de la red, la carga de trabajo, p. ¿está haciendo un trabajo diferente? ¿Cuán ocupados están los recursos que se están cerrando? si se conectan a una base de datos o servicio, todos marcan la diferencia en este caso. La versión del kernel podría marcar la diferencia, pero primero verificaría la primera lista. –

+0

Si tiene una versión anterior de Java, la versión de 64 bits puede usar más memoria que la versión de 32 bits. Si tiene la última versión, la diferencia es mucho menor (ya que usa '-XX: + UseCompressedOops') La verdadera solución es arreglar el código, no jugar con la JVM. –

2

El hilo finalizador raramente debería estar haciendo mucho trabajo. Los recursos ya deberían haber sido liberados. Asegúrese de que su código maneje los recursos de la manera estándar.

Java SE 7:

try (final Resource resource = acquire()) { 
    use(resource); 
} 

Pre-Java SE 7:

final Resource resource = acquire(); 
try { 
    use(resource); 
} finally { 
    resource.release(); 
} 
0

Como Tom Hawtin señala, se puede controlar la FinalizerThread mediante la creación de un método finalize() que llama Thread.currentThread() y luego lo esconde en una estática. Probablemente también puedas cambiar su prioridad.

Pero hay una gran posibilidad de que no sirva de nada. Es probable que solo haya un hilo de finalizador. Y el problema es probable que sea ya sea que:

  • el hilo no puede seguir el ritmo porque hay simplemente demasiado trabajo por hacer, o
  • el hilo está siendo bloqueada por algo que está haciendo en el finalizador métodos.

(Y, yo esperaría que el subproceso finalizador a ya ser marcado como de alta prioridad.)

Pero de cualquier manera, creo que es una mejor solución para deshacerse de los métodos finalize(). Apuesto a que están haciendo algo que es innecesario ... o dudoso. En particular, usar finalizadores para reclamar recursos de objetos caídos es una forma pobre de resolver ese problema en particular. (Consulte la respuesta de Tom Hawtin.)

+0

¿Conseguir el objeto del hilo del finalizador? Fácil. Cree un objeto con un finalizador que guarde 'Thread.currentThread()' en una estática. –

Cuestiones relacionadas