Administracion de Memoria Java

download Administracion de Memoria Java

of 65

Transcript of Administracion de Memoria Java

  • Administracin de memoria en Java

    http://javacuriosities.blogspot.com.ar/

  • Temario Qu es la memoria?

    Quin esta a cargo del manejo de la memoria en Java?

    reas de memoria (Runtime Data Areas)

    - Stack

    - Heap rea

    - Non-Heap rea

    Qu pasa cuando ejecutamos nuestro programa Java?

    Ciclo de vida de los objetos

    Size of tipos primitivos vs Wrappers

    Size of Objetos

    Modelo de memoria de la JVM y sus parmetros

    Garbage Collector

    Que es un OOM (Out Of Memory)?

    Qu tipos de OOM podemos encontrar?

    Administracin de memoria en Java

  • Que es la memoria?

    La memoria es la parte utilizada por los sistemas informticos para

    almacenar informacin en tiempo de ejecucin, o sea estamos hablando de

    memoria voltil, por lo cual su contenido se pierde cuando se apaga el

    equipo.

    Administracin de memoria en Java

  • Quin esta a cargo del manejo de la memoria en Java?

    La JVM (Java Virtual Machine) es la encargada de ejecutar nuestros

    programas Java, pero a su vez es la que esta a cargo de reservar, asignar

    y liberar la memoria utilizada por nuestra aplicacin.

    La arquitectura de la JVM contiene diversas partes las cuales cumplen

    distintos objetivos al referirnos al manejo de memoria debemos mencionar

    estamos hablando del rea llamada Runtime Data Areas

    Administracin de memoria en Java

  • Administracin de memoria en Java

    Estructura de la JVM

  • reas de memoria (Runtime Data Areas)

    Administracin de memoria en Java

  • Stack

    Administracin de memoria en Java

  • Administracin de memoria en Java

    Cada thread creado por la JVM posee su propio PC Register (Program

    Counter) y su propio Stack Frame.

    Program Counter

    - Es el encargado de mantener un puntero a la instruccin que esta siendo

    ejecutada en un determinado momento por un hilo en particular, se va ir

    desplazando por el cdigo.

    Stack Frame

    - Frame: Cada mtodo invocado crea un nuevo frame, este es usado para

    almacenar datos y resultados parciales, solo un frame esta activo a la vez. El

    frame es destruido cuando finaliza la invocacin del mtodo esta puede ser de

    manera normal o abrupta.

    - Local Variables: Cada frame contiene un array con sus propias variables

    locales.

    - Operand Stack: Cada frame contiene una pila, cuando un nuevo frame es

    creado este se encuentra vaco, en esta estructura se van alocando las

    instrucciones a ejecutar.

  • Heap Area & Non-Heap Area

    Administracin de memoria en Java

  • Heap Area

    Administracin de memoria en Java

    El Heap es el espacio de memoria en donde se almacenan las instancias

    de clases (Objetos) y arreglos. Esta puede crecer o ser reducida

    automticamente bajo demanda. El Garbage Collector (GC) es el

    encargado de reclamar el espacio que los objetos van liberando. Esta rea

    es compartida por todos los threads.

    Podemos identificar las siguientes dos partes

    Young Generation

    - Eden Space: Esta es el rea inicial donde se inicializan la mayora de los

    objetos.

    - Survivor Space: En esta rea se almacenan los objetos que han sobrevivido a

    la recoleccin de basura en el Eden. En general esta rea esta dividida en dos

    partes From y To.

    Old Generation

    - Tenured Space: Contiene los objetos que han existido por un tiempo largo y

    que han pasado por el Survivor space.

  • Non-Heap Area

    Administracin de memoria en Java

    Esta rea incluye los objetos que son considerados parte de la JVM. Al

    igual que el heap esta puede crecer o ser reducida automticamente bajo

    demanda. Dependiendo de la implementacin de la JVM el GC puede

    actuar sobre esta rea o compactarla. Esta rea es compartida por todos

    los threads.

    Podemos identificar las siguientes dos partes

    Permanent Generation

    - Este espacio contiene todos los datos reflectivos de la JVM como por ejemplo

    clases y mtodos. Adems contiene la estructura por clase (Propiedades, Firma

    de mtodos e implementacin de mtodos). Esta rea adems contiene dos

    espacios llamados Shared-RO and Shared-RW

    Code Cache

    - Contiene la memoria usada para el cdigo compilado por el JIT compiler y

    almacenado de cdigo nativo

  • Administracin de memoria en Java

    Runtime Constant Pool

  • From Permanent Generation To Metaspace

    Administracin de memoria en Java

    Debido a que algunas implementaciones no usan este espacio y usan

    espacio nativo, la gente de Oracle decidi eliminar esta rea y usar un

    nuevo llamado Metaspace. Este cambio se espera para JDK 8.

    Resize automtico de esta rea

    Algunas cosas se movieron al Heap

    Nuevo flag MaxMetaspaceSize

    Recoleccin automtica al alcanzar el valor definido antes

  • Ejemplo

    Administracin de memoria en Java

    HelloWorld.java

    RuntimeConstantPool.java

  • Qu pasa cuando ejecutamos nuestro programa Java?

    Administracin de memoria en Java

  • Administracin de memoria en Java

  • Classloaders

    Administracin de memoria en Java

    Bootstrap Classloader carga el API bsica de Java e inicia el System Class Loader.

    El System Classloader enva los archivos .class por medio de un stream binario a la JVM.

    Usando ese stream la JVM obtiene la siguiente informacin

    - Constantes, literales.

    - Paquetes, modificadores, variables estticas.

    - Informacin de atributos.

    - Informacin de mtodos.

    - Referencias al Classloader y a la Clase.

    Esta informacin es almacenada en el Method Area.

    Se crea el Thread-Main el cual busca el mtodo main (Recordar que cada thread tiene su propio Stack).

    El Program Counter va ejecutando el cdigo, usando las distintas reas de memoria.

  • Para recordar acerca de los Classloaders

    Administracin de memoria en Java

    Delegation (Delegacin): El Classloader actual siempre va a delegar la tarea de carga la clase a su padre antes de intentar

    cargarla el mismo.

    Visibility (Visibilidad): Las clases cargadas por los Classloaders padres son vistas por todos los hijos pero no de modo inverso.

    Uniqueness (Unicidad): Una vez que la clase es cargada por cualquiera de sus Classloaders padres, el hijo nunca volver a

    cargarla.

    Configurable (Configurable): La mayora de servidores de aplicaciones crean sus propios Classloaders utilizando como

    padre al System Classpath Classloader

  • Ejemplo

    Administracin de memoria en Java

    ClassLoaderDelegation.java

  • Ciclo de vida de los objetos

    Administracin de memoria en Java

    Class Loading

    - La primera vez que se crea un objeto de esa clase.

    - Cuando se accede a una propiedad o mtodo esttico de esa clase por primera vez.

    Inicializadores estticos

    - Inmediatamente despus de cargar la clase se ejecutan los inicializadores estticos

    de la clase.

    Creacin del objeto

    Un objeto es una instancia de una clase, la creacin de un objeto tiene tres

    partes.

    - Declaracin

    - Instanciacin

    - Inicializacin

    Uso del objeto

    Limpieza (Mtodo Finalize y luego GC)

  • Ejemplo

    Administracin de memoria en Java

    LifeCycle.java

  • Size of tipos primitivos vs wrappers

    Administracin de memoria en Java

    Primitive Type Size (Bytes) Wrapper Type Size (Bytes)

    char 2 Character 16

    byte 1 Byte 16

    short 2 Short 16

    int 4 Integer 16

    long 8 Long 16

    float 4 Float 16

    double 8 Double 16

    boolean 1 Boolean 16

    Como se puede observar la diferencia entre usar tipos primitivos y

    usar sus wrappers puede ser bastante grande.

  • Ejemplos

    Administracin de memoria en Java

    SizeOfPrimitives.java

    SizeOfWrappers.java

  • Size of Objetos

    Administracin de memoria en Java

    Como vimos antes los wrappers pueden consumir mucha memoria,

    pero lo importante es entender el porque de esto.

    Reglas:

    Objetos:

    - El tamao base de cualquier objeto es 8 bytes.

    - El tamao total de un objeto siempre es mltiplo de 8 (Esto se lo conoce como

    padding)

    Atributos:

    - Si el tipo del atributo es primitivo ocupa el size que le corresponde.

    - Si el tipo del atributo es un objeto, entonces ocupa 4 bytes porque es una

    referencia.

    Arrays:

    - Array de primitivos ocupa: 8 (Base) + 4 (Length) + Length * size del tipo primitivo.

    - Array de objetos ocupa: 8 (Base) + 4 (Length) + Length * 4 (Size de una

    referencia).

  • Shallow size vs. Retained size

    Administracin de memoria en Java

    Figura 1:

    Objeto 1: Retained size obj1, obj2, obj4

    Objeto 2: Retained size obj2, obj4

    Figura 2:

    Objeto 1: Retained size obj1, obj2, obj3, obj4

    Objeto 2: Retained size obj2, obj3, obj4

  • Ejemplos

    Administracin de memoria en Java

    SizeOfObjects.java

    ShallowVsRetained.java

  • Modelo de memoria de la JVM

    Administracin de memoria en Java

    Debemos tener en cuenta que la mxima memoria que podemos asignar a un

    proceso Java va a depender del Sistema Operativo (SO) y de la JVM que

    estemos usando.

    JVM 32 bits: Valor mximo aproximado 2GB.

    JVM 64 bits: Valor muy superior a la de 32 bits. Aproximadamente (2^48).

  • Parmetros de memoria

    Administracin de memoria en Java

  • Administracin de memoria en Java

    -Xms = Mnimo tamao del Heap.

    -Xmx = Mximo tamao del Heap.

    -XX:NewSize = Tamao inicial del Eden + Survivor Space.

    -XX:MaxNewSize / -Xmn = Mximo tamao de Young Generation.

    -XX:PermSize = Mnimo tamao del PermGen (Permanent Generation).

    -XX:MaxPermSize = Mximo tamao del PermGen (Permanent Generation).

  • Parmetros JVM

    Administracin de memoria en Java

    Parmetro Definicion Ejemplo

    -Xms Minimo tamao del Heap -Xms512M

    -Xmx Maximo tamao del Heap -Xmx512M

    -XX:NewSize Tamao inicial del Eden + Survivor Space -XX:NewSize=128M

    -XX:MaxNewSize / -Xmn Mximo tamao de Young Generation -XX:MaxNewSize=128M

    -XX:NewRatio Ratio entre Young y Old generation -XX:NewRatio=3

    -XX:SurvivorRatio Ratio entre Eden y Survivor -XX:SurvivorRatio=6

    -XX:PermSize Mnimo tamao del PermGen (Permanent Generation) -XX:PermSize=64M

    -XX:MaxPermSize Mximo tamao del PermGen (Permanent Generation) -XX:MaxPermSize=128M

    -Xss -XX:ThreadStackSize Tamao de cada stack de cada Thread -XX:ThreadStackSize=256k

    -XX:MinHeapFreeRatio Indica el minimo de Heap libre antes de pedir memoria -XX:MinHeapFreeRatio=40

    -XX:MaxHeapFreeRatio Indica el maximo de Heap libre antes de liberar memoria -XX:MaxHeapFreeRatio=70

    -XX:TargetSurvivorRatio Indica hasta que porcentaje se puede llenar el Survivor antes de mover al Old -XX:TargetSurvivorRatio=90

  • Ejemplos

    Administracin de memoria en Java

    JVMParameters.java

    MemoryViewer.java

  • Administracin de memoria en Java

    La Recoleccin de basura automtica es el proceso de buscar en la

    memoria y liberar aquellos objetos que estn disponibles para ser

    recolectados, podemos identificar dos tipos de objetos

    Reachable (Objeto sobre el cual aun hay referencias) : Significa que alguna

    parte de nuestro programa todava mantiene una o mas referencias a ese

    objeto.

    Unreachable (Objeto el cual no puede ser referenciado): Ya no se hace

    referencia en ninguna parte del programa no hay forma de obtener la

    referencia a ese objeto. As que la memoria utilizada por un objeto no

    referenciado puede ser reclamada.

    En un lenguaje de programacin como C, asignar y desasignar la memoria

    es un proceso manual. En Java, el proceso de cancelar la asignacin de

    memoria es manejado automticamente por el recolector de basura.

    Garbage Collector

  • Garbage Collector Behaviour

    Administracin de memoria en Java

  • Administracin de memoria en Java

    Lnea #6 Lnea #8

    Lnea #11

    System.runFinalization(): Le sugiere a la

    JVM a ejecutar el mtodo finalize de los

    objetos que estn en la cola de finalizacin.

    System.gc(): Le sugiere a la JVM ejecutar el

    garbage collector para reclamar espacio y

    liberar memoria.

  • Administracin de memoria en Java

    Tipos de recolecciones

    Existen dos tipos de recolecciones

    Minor GC

    - Ejecutado en el Young Generation, cuando el Eden se encuentra lleno o antes

    de incrementar el espacio de esta rea se ejecuta esta recoleccin. Aqu se usa

    un algoritmo de copia.

    Full GC

    - Ejecutado en el Tenured Generation, cuando el Old se encuentra lleno se

    ejecuta esta recoleccin o antes de incrementar el espacio de esta rea. Aqu

    se puede usar el algoritmos MSC(Mark- Sweep- Compact) o CMS (Concurrent

    Mark Sweep), este ultimo no compacta los objetos luego de su ejecucin lo cual

    genera que pedir memoria sea un poco mas complejo. Incluye el PermGen en

    su recoleccin.

  • Administracin de memoria en Java

    Algoritmo de Copia (Paso 1)

  • Administracin de memoria en Java

    Algoritmo de Copia (Paso 2)

  • Administracin de memoria en Java

    Algoritmo de Copia (Paso 3)

  • Administracin de memoria en Java

    Algoritmo de Copia (Paso 4)

  • Administracin de memoria en Java

    Algoritmo de Copia (Paso 5)

  • Administracin de memoria en Java

    Algoritmo de MSC (Paso 1)

  • Administracin de memoria en Java

    Algoritmo de MSC (Paso 2)

  • Administracin de memoria en Java

    Algoritmo de MSC (Paso 3)

  • Administracin de memoria en Java

    Algoritmo de CMS

    N Fase Descripcion

    1 Initial Mark

    (Stop the World Event) Es una pausa pequea donde todos los objetos "reachable" son marcados.

    2 Concurrent Marking Busca objetos vivos mientras la aplicacin se ejecuta en otro hilos.

    3 Remark

    (Stop the World Event) Busca los objetos que no fueron encontrados durante la parte 2.

    4 Concurrent Sweep Remueve los objetos que son "unreachable", es importante notar que los objetos

    "reachable" no son movidos, o sea no hay compactacion.

    5 Resetting Se prepara para la siguiente ejecucin limpiando las estructuras usadas.

  • Administracin de memoria en Java

    Tipos de GC por reas de memoria

  • Administracin de memoria en Java

    Young Generation:

    "Serial" corre en un solo hilo y es del tipo STW (Stop-the-world).

    "Parallel Scavenge" corre en mltiples hilos y aunque es del tipo STW (Stop-the-world), obtiene una mejor performance.

    "ParNew" es igual que el "Parallel Scavenge" pero esta mejorado para trabajar de forma concurrente con "CMS".

    Tenured Generation:

    "Serial Old" corre en un solo hilo y es del tipo STW, usa el algoritmo Mark-Sweep-Compact.

    "Parallel Old" corre en mltiples hilos, tambin es del tipo STW.

    "CMS" corre de forma concurrente la mayor parte del tiempo y tiene pequeas pausas donde se ejecuta en forma STW.

  • Administracin de memoria en Java

  • Administracin de memoria en Java

  • Administracin de memoria en Java

    GC Collectors

    JVM Young Collector Tenured Collector

    -XX:+UseSerialGC Serial Serial Old (MSC)

    -XX:+UseParNewGC ParNew Serial Old (MSC)

    -XX:+UseParallelGC Parallel Scavenge Serial Old (MSC)

    -XX:+UseParallelOldGC Parallel Scavenge Parallel Old

    -XX:-UseParNewGC

    -XX:+UseConcMarkSweepGC Serial CMS + Serial Old (MSC)

    -XX:+UseParNewGC

    -XX:+UseConcMarkSweepGC ParNew CMS + Serial Old (MSC)

    -XX:+UnlockExperimentalVMOptions

    -XX:+UseG1GC G1

  • Administracin de memoria en Java

    JVM Ergonomics

    Desde el JDK 5.0 la JDK detecta en que tipo de maquina esta y cambia su

    configuracin, modo cliente o modo servidor.

    Estos cambios incluyen:

    - Configuracin de memoria mnima y mxima para el Heap.

    - Seleccin automtica del GC.

    - Activa el resize automtico para el rea Young y Tenured.

    - Otras configuraciones adicionales.

  • Administracin de memoria en Java

    Analizando el GC (Parmetros)

    Parmetro Definicion

    -verbose:gc Imprime informacion por consola del GC

    -Xloggc:GCLogs.log Guarda la misma informacin que -verbose:gc en un archivo que le indiquemos pero adems agrega mas detalle

    -XX:+PrintGCDetails Imprime el detalle de cada recoleccion

    -XX:+PrintGCDateStamps Imprime DateStamps para cada GC (Dia+Hora+Minutos+Segundos+Milisegundos)

    -XX:+PrintGCTimeStamps Imprime el TimeStamp para cada recoleccion

  • Administracin de memoria en Java

    Analizando el GC (Revisando el output)

  • Ejemplos

    Administracin de memoria en Java

    GCMXBean.java

    GCDetails.java

  • Que es un OOM (Out Of Memory)?

    Administracin de memoria en Java

    Este es el error que se suele producir debido a que la JVM se

    queda sin memoria disponible.

    Existen varios tipos de OOM y en base a cual de ellos nos

    estemos enfrentando sabremos si es porque la JVM se que sin

    memoria en una rea o en otra.

  • Tipos de OOM

    Administracin de memoria en Java

    java.lang.OutOfMemoryError: unable to create new native thread

    - OOM en la memoria nativa, esta rea no es controlada por nosotros sino que la maneja el SO (Sistema

    Operativo).

    Java 32-bit Native Heap = Max Process Size Java Heap PermGen

    Java 64-bit Native Heap = Memoria Fisica & Virtual Java Heap PermGen

    java.lang.OutOfMemoryError: Java heap space

    - OOM en el Java Heap, esto se produce cuando tenemos demasiados objetos en memoria o tenemos

    un posible Memory Leak (Fuga de memoria).

    java.lang.OutOfMemoryError: PermGen space

    - OOM en el PermGen Space, esto se produce porque estamos cargando muchas clases por nuestra

    aplicacin, o almacenando muchos String en la cache de constantes o en servidores de aplicaciones

    donde intentamos desplegar la aplicacin y los ClassLoader quedan referenciados.

    java.langOutOfMemoryError: GC overhead limit exceeded

    - Este error sucede cuando el GC esta gastando mucho tiempo en limpiar la memoria y la memoria

    recuperada en muy poca.

    java.lang.OutOfMemoryError: Requested array size exceeds VM limit

    - Este error sucede porque estamos intentando crear un vector mas grande que nuestro heap.

  • Ejemplos

    Administracin de memoria en Java

    OOMNativeHeap.java

    OOMJavaHeapSpace.java

    OOMPermGenSpace.java

    OOMRequestArraySize.java

  • OOM vs Memory Leak

    Administracin de memoria en Java

    No todo OOM indica una fuga de memoria (Memory Leak)

    - Puede haber una fuga de memoria.

    - La aplicacin puede necesitar mas memoria.

  • Heap Dump

    Administracin de memoria en Java

    Un Heap dump es una foto de la memoria de un proceso Java

    en un determinado momento.

    Dependiendo de la JVM el Heap dump puede contener una

    informacin o otra, adems en general antes de ejecutar el

    volcado un recoleccin completa es ejecutada (Full GC).

  • Obteniendo un Heap Dump

    Administracin de memoria en Java

    Aplicacin Externa

    Alguna aplicacin externa como VisualVM.

    HeapDumpOnOutOfMemoryError

    Cuando la aplicacin arroje un OOM se generara un heap dump, usando el HeapDumpPath

    configurado.

    Jmap

    Tool que viene incorporada en el jdk.

    jmap -dump:file=

    Jmap (Desde la aplicacin)

    Podemos usar los MXBean para ejecutar el jmap desde la aplicacin.

    HotSpotDiagnosticMXBean(Usando Reflection)

    Usando el DiagnosticMXBean para hacer el dump

  • Heap Dump (Parmetros JVM)

    Administracin de memoria en Java

    Parmetro Definicion Ejemplo

    -XX:+HeapDumpOnOutOfMemoryError Activa la generacion de un Heap Dump frente a un OOM -XX:+HeapDumpOnOutOfMemoryError

    -XX:HeapDumpPath Indica el Path para el Heap Dump -XX:HeapDumpPath=C:\temp

  • Ejemplo

    Administracin de memoria en Java

    MainHeapDump.java

    HeapDumpPath.java

  • Analizando un Heap Dump (Puntos clave 1)

    Administracin de memoria en Java

    Revisar memoria consumida y numero de instancias.

    - Wrappers grandes consumidores de memoria.

    Histogram

    - Nos muestra la cantidad de objetos por cada clase.

    Analizar el Dominator Tree

    - Esta estructura nos muestra los objetos mas grandes, aqu debemos ver que la lista esta

    compuesta de lo que esperamos, en general aqu podremos ver cache no liberadas.

    Group By por clase

    - Esta opcin nos permite ver la memoria que consume cada clase, de esta forma

    podremos detectar objetos que se repiten varias veces y consumen un gran volumen.

    Group By por value

    - En general para analizar si tenemos Wrappers duplicados.

    Keep Unreachable objetcs

    - Debemos prender esta opcin en el MAT para que no elimine los objetos que serian

    unreachables.

    Object Query Language (OQL)

    - Lenguaje de consulta que nos deja interactuar con los objetos del Heap.

  • Analizando un Heap Dump (Puntos clave 2)

    Administracin de memoria en Java

    Revisar GC Roots

    - El Garbage collector recorre la memoria usando GC roots, lo cuales son porciones de memoria que

    pueden ser accedidas desde afuera del Heap.

    - Local Variables.

    - Thread activos.

    - Variables estticas.

    - Referencias JNI

    Shallow size vs. Retained size

    - Shallow size: Es el espacio ocupado por el objeto en si mismo.

    - Retained size: Es el espacio ocupado por el objeto en si mismo mas la suma de todos los shallow sizes

    que son accedidos directamente o indirectamente solo desde este objeto

  • JDK Tools

    Administracin de memoria en Java

    Jps

    - Nos brinda informacin de los procesos Java corriendo en nuestra computadora y no

    entrega el PID.

    Jmap

    - Nos ofrece informacin de las reas de memoria del proceso Java indicado y adems nos

    permite generar Heap Dumps y Histogramas.

    Jhat

    - Herramienta de anlisis del Heap, es experimental y puede no estar incluida en futuras

    versiones.

    Jstat

    - Nos brinda informacin estadstica sobre el proceso Java que le indicamos, esta

    estadsticas incluyen tiempo del GC, JIT Compiler, Classloaders.

    Jstack

    - Ejecuta un Thread Dump o sea un volcado de cada Thread.

    Jinfo

    - Brinda informacin de configuracin de un proceso Java.

  • Links

    Administracin de memoria en Java

    VisualVM

    http://visualvm.java.net/

    Memory Analyzer (MAT)

    http://www.eclipse.org/mat/downloads.php

    GCViewer

    https://github.com/chewiebug/GCViewer/wiki/Changelog

    Jprofiler

    http://www.ej-technologies.com/products/jprofiler/overview.html