yugioh solucion outofmemoryerror exceeded example español collector java garbage-collection out-of-memory finalize

java - solucion - Los objetos no están finalizados y el finalizador no está haciendo nada



java.lang.outofmemoryerror gc overhead limit exceeded solucion (2)

Creemos que estaba relacionado con la versión 1.6.0_30 de OpenJDK. Después de actualizar a Oracle JDK 1.7.0_51, el problema desapareció. Y probablemente apareció después de la actualización automática de openJDK, pero tampoco podemos confirmarlo. No pudimos encontrar un informe de error relevante.

En nuestro servidor, comenzamos a tener problemas con OutOfMemoryError . Analizamos los volcados de almacenamiento dinámico utilizando Eclipse Memory Analysis, y descubrimos que se realizaron muchos objetos para finalizar (aproximadamente 2/3 del montón):

Encontramos que podría ser un método de bloqueo de finalize (). Encontré varios informes de errores de este problema ( aquí o aquí ), y siempre se manifestó en la pila de hilos de Finalizer, que estaba bloqueado en algún lugar. Pero en nuestro caso, este hilo estaba ESPERANDO:

"Finalizer" daemon prio=10 tid=0x43e1e000 nid=0x3ff in Object.wait() [0x43dfe000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x4fe053e8> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:133) - locked <0x4fe053e8> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:149) at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:189)

EDITAR:

Luego tratamos de agregar -XX:+UseConcMarkSweepGC , pero sin éxito, solo disminuyó la frecuencia de OutOfMemoryError , así que primero pensamos que OutOfMemoryError .

Finalmente, sospechamos que la falla de JVM y la actualización de OpenJDK 1.6.0_30 a Oracle JDK 1.7.0_51, y el problema desapareció (al menos parece que durante las últimas 4 horas el montón utilizado no crece). No recordamos ningún cambio en el método de finalización, ni actualizamos ninguna biblioteca, solo hubo desarrollos menores durante ese tiempo. El problema no se reproduce en nuestro servidor de prueba, con la misma configuración, excepto que es JVM de 64 bits, mientras que el servidor de producción es de 32 bits.

La pregunta es: ¿cuál podría ser la causa de que los Objetos no estén finalizados y el hilo del Finalizer esperando el siguiente objeto? ¿Analizamos el volcado del montón correctamente?

Gracias por todas las respuestas.


El subproceso Finalizer tiene baja prioridad, por lo que pasará una buena cantidad de tiempo WAITING lugar de finalizar. No concluiría de esa pila que el hilo está bloqueado; simplemente se cede el control a otros hilos. En su lugar, es probable que esté introduciendo un número patológico de objetos en la cola del finalizador y la JVM simplemente no puede mantener el ritmo.

Desafortunadamente, hay demasiadas explicaciones posibles de por qué este comportamiento cambió entre las versiones para identificar una causa exacta, pero aquí hay una posible explicación. Oracle 7 Java tiene un recolector de basura nuevo y más eficiente. Es razonable imaginar que la carga aligerada en el GC significa que la cola del finalizador tiene más tiempo en el procesador y, por lo tanto, puede mantenerse al día con la cantidad de objetos que se le agregan.

Sin embargo, independientemente de la causa subyacente, la solución correcta es reducir el uso de finalizadores. Excepto en circunstancias muy limitadas, introducen más problemas de los que resuelven, entre los que no se encuentran el GC y la sobrecarga de memoria. Si alguna vez te encuentras investigando objetos que están pendientes de la finalización de la limpieza, estás construyendo demasiados objetos finalizables.