11

Aquí está mi caso de uso. Estamos tratando de reducir una posible pérdida de memoria en una aplicación, y estamos utilizando una herramienta de análisis de memoria para hacer una instantánea del montón para que podamos buscar instancias de objetos y referencias. (En caso de que sirva, estamos usando YourKit.)¿Hay alguna forma de obligar a los objetos débiles y/o de referencia suave a pasar GC en Java?

Esta aplicación hace un uso extensivo de proxies dinámicos y CGLIB, que terminan almacenando toneladas de referencias a clases y cargadores de clases en WeakHashMaps.

Después de ejecutar nuestro caso de prueba, esperamos que todas las referencias al objeto X y su cargador de clases desaparezcan, pero dado que al final hubo muchos proxies involucrados en el caso de prueba, tenemos muchas referencias débiles/débiles. . (Solo puedo encontrar referencias de WeakHashMap, pero YourKit ajusta las referencias débiles y débiles en una línea en el resumen, así que no puedo estar seguro de que no me falte una referencia suave en algún lugar).

Esto es cierto incluso después solicitando un GC completo de la JVM. (Usando el sol 1.6.0_23 JDK en modo de servidor.)

Se parece como si admite la JVM sólo hay débiles referencias/suavemente a estos objetos, pero no puedo conseguir forzarlo a GC estas cosas estar 100% seguro. (Entonces, lo que quiero es que esto desaparezca completamente del montón y su uso del cargador de clases de permgen también se vaya).

Alguien sabe de una forma de configurar y/o forzar a la JVM a deshacerse de los objetos solo/débilmente referenciado?

+0

¿Ha registrado sus objetos en eventos globales por casualidad? Tal vez un campo estático (u otro objeto de subproceso u otra cosa) tiene una referencia a ellos ... – Mehrdad

+0

Buena pregunta: ya se había investigado esto y YourKit proporciona suficiente información para encontrar este tipo de cosas rápidamente. Mientras todavía estoy investigando, hasta ahora reduje esto (creo) a algún comportamiento iniciado por Spring's AOP cuando proxies clases/métodos usando RegexpMethodPointcutAdvisor. SIN EMBARGO, este es solo un caso especial (hasta ahora) de este asesor; lo usamos en numerosos lugares que NO parece crear este problema. Todavía estoy trabajando para identificar lo que es único sobre el caso que lo hace ... publicaré cuando tenga más. – Scott

+0

Ok, esta es la actualización. Creo que encontré el arma humeante para mi problema en particular. Uno de los proxies utilizados en nuestra aplicación carga su implementación de forma perezosa cuando es necesario desde un caché para garantizar que la operación siempre ocurra en el último objeto en caché. Si la memoria caché no tiene el objeto, la memoria caché se ha configurado para instanciar e inicializar el objeto. El proxy es un proxy bastante tonto que, para cualquier invocación de método, le pide al caché el objeto, luego invoca el método en el objeto. Los comentarios tienen un límite de caracteres, así que sigue leyendo ... – Scott

Respuesta

10

Llamar a GC siempre debe liberar todos los objetos débilmente alcanzables (suponiendo que la "solicitud" realizada al llamar al System.gc está realmente garantizada). Si GC no elimina las referencias débiles, significa que los objetos son al menos accesibles.

Borrar las referencias suaves es más complicado, ya que esto es a discreción de la JVM. La única manera de garantizar el despeje de objetos de alcance reducido es provocar el lanzamiento de un OutOfMemoryError. Este truco se demuestra en this discussion.

+1

¿No es 'System.gc' solo una pista?Y, por lo tanto, ¿no es la respuesta a la pregunta "no"? – nmr

+1

Me pregunto si esto funciona en Dalvik/ART – nmr

Cuestiones relacionadas