Buenas prácticas usando Hibernate

Hibernate es un gran motor objeto-relacional (ORM) y una de las principales influencias en el standard JPA.

Pero el uso de un ORM también puede causar problemas si no tenemos en cuenta unas ciertas buenas prácticas. Por suerte existe mucho material al respecto:

· Capítulo 24 de la documentación de Hibernate

· Real-World Experiences With Hibernate – Best Practices

· Hibernate Querying 101 : tips and tricks

Un buen resumen es este: Don’t Get Caught Hibernating

Búsqueda de Memory Leaks mediante Eclipse MAT

Búsqueda de Leaks con MAT (Memory Analyzer Tool)

Lo primero es hacer el volcado de memoria con el jmap:

>jmap -dump:file=heap.hprof <pid>

o

>jmap -dump:file=heap.bin <pid>

Luego abriremos el fichero que contiene el dump (normalmente .bin, .hprof o hpd) mediante el MAT a través de la opción “File > Open Heap Dump” y una vez procesado nos aparece la página “Overview”.

A la derecha de esta página encontramos el tamaño del dump y el número de clases, objetos y cargadores de clases que contiene. En el pie de la gráfica se nos indica los objetos más grandes que hay en el dump.

Si movemos el ratón sobre un “trozo de la tarta” veremos su detalle en el “Object Inspector” de la izquierda. Si hacemos click en uno de los trozos se despliega un menú de contexto con distintas opciones para explorar por ejemplo los objetos referenciados que forman parte del trozo.

Ahora vamos a ver qué podemos hacer para detectar leaks,

Si el “leak” es inducido por un único componente (objeto, ClassLoader, etc…), será mostrado directamente en el pie de la gráfica en el panel “Overview”. Se suelen presentar normalmente varios sospechosos de “leak”.

También podemos es usar el informe de sospechosos de leak (“Leak Suspects”) del menú o en el apartado “Reports” de la pestaña “Overview”.

donde se nos abre una nueva pestaña similar a la siguiente:

En dicha pestaña se indican los posibles problemas de leaks que pueden estar produciéndose.

Si el leak no es inducido por un único objeto o unos pocos objetos, pueden pasar varias cosas:

§ El sospechoso de leak podría no mostrarse en el informe en el “Overview” o en el top del “dominator tree” o

§ El leak podría ser inducido por una clase de objetos, en tal caso

o Abrir el dominator tree desde la toolbar usando el botón

o Seleccionar “Group result by…” desde la toolbar y seleccionar “Group by class”.

o Una vez que se encuentra la clase sospechosa de leak, podemos listar sus objetos y encontrar los objetos que mantienen referencias a ella.

§ Seleccionamos la “List Objects à by incoming references” desde el menú de contexto. Como resultado obtendremos una gráfica de referencias de objetos.

§ Escudriñar la gráfica para encontrar referencias.

§ Si vamos a analizar las referencias de una única clase, es mejor usar “Show objects by class à by incoming references”.

§ Usamos “Immediate Dominators” para obtener la lista de objetos que referencian a uno dado. Se pueden excluir los que paquetes que consideremos oportunos.

§ La forma más sencilla de encontrar lo que mantiene “vivos” a los objetos que provocan el “leak” es chequear el “path” hacia los “garbage collection roots”.

Seleccionamos un objeto y en el menú contextual seleccionamos “Path to GC Roots” y excluimos las referencias “phantom/weak/soft”

§ Para encontrar el leak a nivel de clase, usamos la query “Merge Shortest Path to GC Roots”. Esto nos muestra los caminos más cortos desde el “GC Roots” hacia cada una de las instancias de la clase seleccionada.

§ El “path to GC roots” por objeto y por clase nos da una idea de las referencias de más compleja a menos hacia la clase sospechosa.

Problemas con PermGen (JVM Hotspot) – ClassLoader leak

Muchos contenedores web usan cargadores de clases separados para cargar cada aplicación web. Si este cargador de clases no es recolectado por el GC cuando la aplicación es parada/reiniciada tenemos un “ClassLoader leak”.

Seleccionamos “Java Basics -> Class Loader Explorer” para obtener una visión de la lista cargadores de clases, las clases que ellos definen y el número de número de objetos cargados.

§ Para chequear las referencias al cargador de clases, click derecho en el cargador de clases y seleccionamos “ClassLoader -> Path to GC Roots”.

§ Si las referencias son únicamente mantenidas por ejemplo por el contextClassLoader de un thread, podría ser debido a un mal uso del mismo.

Seleccionamos “Java Basics -> Duplicate Classes” para obtener una lista de las clases que se han cargado en varios cargadores de clases.

§ Si notamos que una clase debería haber sido cargada solo una vez, podemos identificar el cargador de clases que provoca el leak chequeando el “Path to GC Roots” del cargador de clases que ha cargado esa clase duplicada

Es muy recomendable echarle un vistazo al artículo http://java.jiderhamn.se/2011/12/11/classloader-leaks-i-how-to-find-classloader-leaks-with-eclipse-memory-analyser-mat/ en el que se explica cómo encontrar y solucionar problemas de ClassLoaders Leaks.

HTML5 WebSocket Refcard

Ya hemos dedicado varios posts al nuevo e interesante estándar de HTML5 WebSocket.

En este post hacemos referencia a un nuevo y completo Refcard de DZone:

En el que se tratan conceptos como las ventajas que ofrece, Servidores WebSockets para diversas tecnologías, API Javascript.

Especialmente interesante es la parte dedicada al despliegue en aplicaciones WebSockets:

En el modelo tradicional de aplicaciones Web:

En el modelo HTML5 con WebSockets: