2011-12-13 6 views
12

Tengo un volcado de memoria que hice de una aplicación en proceso de extinción. Ha consumido todo el montón disponible (-Xmx1024m). Utiliza com.gargoylesoftware.htmlunit.WebClient para rastrear páginas web. Realiza algunas solicitudes de http por minuto, muere en varios días. Como veo desde el volcado, tiene ~ 1750 instancias de la clase HtmlPage, cada una de ellas tiene tonos de objetos relacionados, incluido el contenido completo de una página rastreada.Detección de fugas de memoria, VisualVM: "No se encontró raíz de GC". ¿Que sigue?

No puedo entender por qué HtmlPage no son basura. Investigué referencias de instancias y no veo ningún código que contenga una referencia al mismo, y VisualVM dice que "No se encontró ninguna raíz de GC". Según entiendo, debería significar que el objeto es elegible para gc, pero no funciona.

La aplicación se ejecuta como un proceso independiente simple, no utiliza contenedores web o servidores de aplicaciones.

¿Alguna pista? ¿Qué más debería ver?

Especificaciones:

  • HtmlUnit v2.7
  • java version "1.6.0_13" Java (TM) SE Runtime Environment (build 1.6.0_13-b03) Java HotSpot (TM) Server VM (build 11.3-b02, modo mixto)
  • Linux my.lan 2.6.18-128.el5 # 1 SMP Mar Dic 17 de 2008 11:42:39 EST i686 i686 i386 GNU/Linux

Update1

he tratado de analizar el volcado por el YourKit Java Profiler. Me muestra un montón de objetos java.lang.ref.Finalizer con 310 MB de tamaño retenido. Se crean para el finalizador net.sourceforge.htmlunit.corejs.javascript.NativeGenerator#finalize(), y el NativeGenerator se refiere a Window, luego al HtmlPage y a todo.

¿Alguien sabe por qué se quedan en la memoria?

Nota: Curioso, pero VisualVM mostró "pendiente de finalización" como cero.

+0

¿Ha utilizado argumentos de línea de comandos específicos para la JVM? –

+0

@ThomasJungblut '-Xmx1024m -XX: MaxPermSize = 128m -XX: + PrintGCDetails -XX: + PrintGCTimeStamps -XX: + UseConcMarkSweepGC' – kan

+0

También estoy experimentando una pérdida de memoria con htmlunit 2.8. Como solución alternativa, vuelvo a instanciar WebClient una vez al día. Espero que puedas rastrear este error. – milan

Respuesta

1

Asegúrese de que está llamando webClient.closeAllWindows() después de que haya terminado con la página (s) - de lo contrario hilo JavaScript sigue incurriendo referencias que sostienen a los recursos de página, etc

+1

setJavaScriptEnabled (falso) '. Intenté hacer una pequeña prueba y parece que funciona bien incluso sin 'closeAllWindows'. Pero sigo intentando ... – kan

+0

Hubiera pensado que la única razón para rastrear con XmlUnit es poder usar JavaScript en las páginas. Oh, bueno;) – maximdim

+0

Algunas otras páginas (que se arrastran en diferentes procesos) usan javascript, sin embargo, esta aplicación en particular no la necesita, pero se rastrea con más frecuencia. – kan

1

Cuando un objeto tiene no método trivial finalize(), al crear una instancia del objeto, la JVM crea java.lang.ref.Finalizer que hace referencia al objeto creado para que no se recolecte la basura antes de que finalice el método finalize(). La pérdida de memoria proviene de esos java.lang.ref.Finalizer-s que no se borran a tiempo. La eliminación de estos finalizadores se realiza mediante un subproceso de daemon de finalizador independiente que tiene menor prioridad, por lo que si crea muchas instancias de objetos con el método finalize() implementado, con el tiempo se quedará sin memoria.

Todo es descrito muy bien en:

http://www.fasterj.com/articles/finalizer2.shtml

Esto es lo que sugieren como solución:

"Una manera obvia es aumentar la prioridad de la 'finalizador' hilo de utilidad - no hay una API para esto, por lo que debe ejecutar todos los hilos para encontrarlo por su nombre, luego aumentar su prioridad ".

Buena suerte

Cuestiones relacionadas