Está en la página 1de 65

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

Estructura de la JVM

Administracin de memoria en Java

reas de memoria (Runtime Data Areas)

Administracin de memoria en Java

Stack

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.

Administracin de memoria en Java

Heap Area & Non-Heap Area

Administracin de memoria en Java

Heap Area
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.
Administracin de memoria en Java

Non-Heap Area
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

Administracin de memoria en Java

From Permanent Generation To Metaspace


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

Administracin de memoria en Java

Ejemplo
HelloWorld.java
RuntimeConstantPool.java

Administracin de memoria en Java

Qu pasa cuando ejecutamos nuestro programa Java?

Administracin de memoria en Java

Administracin de memoria en Java

Classloaders
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
Administracin de memoria en Java
reas de memoria.

Para recordar acerca de los Classloaders


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

Administracin de memoria en Java

Ejemplo
ClassLoaderDelegation.java

Administracin de memoria en Java

Ciclo de vida de los objetos


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)
Administracin de memoria en Java

Ejemplo
LifeCycle.java

Administracin de memoria en Java

Size of tipos primitivos vs wrappers


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.

Administracin de memoria en Java

Ejemplos
SizeOfPrimitives.java
SizeOfWrappers.java

Administracin de memoria en Java

Size of Objetos
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).
Administracin de memoria en Java

Shallow size vs. Retained size

Figura 1:

Figura 2:

Objeto 1: Retained size obj1, obj2, obj4

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

Objeto 2: Retained size obj2, obj4

Objeto 2: Retained size obj2, obj3, obj4

Administracin de memoria en Java

Ejemplos
SizeOfObjects.java
ShallowVsRetained.java

Administracin de memoria en Java

Modelo de memoria de la JVM


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).

Administracin de memoria en Java

Parmetros de memoria

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).

Administracin de memoria en Java

Parmetros JVM
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

Administracin de memoria en Java

Ejemplos
JVMParameters.java
MemoryViewer.java

Administracin de memoria en Java

Garbage Collector
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.

Administracin de memoria en Java

Garbage Collector Behaviour

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
1

Fase
Initial Mark
(Stop the World Event)

2 Concurrent Marking

Remark
(Stop the World Event)

Descripcion
Es una pausa pequea donde todos los objetos "reachable" son marcados.

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

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

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:+UseSerialGC

-XX:+UnlockExperimentalVMOptions
-XX:+UseG1GC

Administracin de memoria en Java

G1

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)

Administracin de memoria en Java

Ejemplos
GCMXBean.java
GCDetails.java

Administracin de memoria en Java

Que es un OOM (Out Of Memory)?


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.

Administracin de memoria en Java

Tipos de OOM
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.

Administracin de memoria en Java

Ejemplos
OOMNativeHeap.java
OOMJavaHeapSpace.java
OOMPermGenSpace.java
OOMRequestArraySize.java

Administracin de memoria en Java

OOM vs Memory Leak


No todo OOM indica una fuga de memoria (Memory Leak)
- Puede haber una fuga de memoria.
- La aplicacin puede necesitar mas memoria.

Administracin de memoria en Java

Heap Dump
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).

Administracin de memoria en Java

Obteniendo un Heap Dump


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=<file-location> <pid>

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

Administracin de memoria en Java

Heap Dump (Parmetros JVM)


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

Administracin de memoria en Java

-XX:HeapDumpPath=C:\temp

Ejemplo
MainHeapDump.java
HeapDumpPath.java

Administracin de memoria en Java

Analizando un Heap Dump (Puntos clave 1)


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.

Administracin de memoria en Java

Analizando un Heap Dump (Puntos clave 2)


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

Administracin de memoria en Java

JDK Tools
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.
Administracin de memoria en Java

Links
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

Administracin de memoria en Java

También podría gustarte