Garbage Collection en el JVM
Click here to load reader
-
Upload
superserch -
Category
Software
-
view
19.573 -
download
0
Transcript of Garbage Collection en el JVM
Garbage CollectorConociendo el manejo de memoria en el JVM
@SuperSerch
¿Qué ocurre en la memoria?
¿Qué ocurre en la memoria?
¿Qué ocurre en la memoria?
¿Qué ocurre en la memoria?
¿Qué ocurre en la memoria?
¿Qué ocurre en la memoria?
¿Qué ocurre en la memoria?
¿Qué ocurre en la memoria?
Retos al administrar la memoria
Velocidad de asignación ( velocidad de creación de objetos )
Seguimiento de objetos y valores vivos
Seguimiento del espacio vacío
Fragmentación de la memoria
JVMS: 2.5.3 HeapThe heap is created on virtual machine start-up. Heap storage for objects is reclaimed by an automatic storage management system (known as a garbage collector); objects are never explicitly deallocated. The Java Virtual Machine assumes no particular type of automatic storage management system, and the storage management technique may be chosen according to the implementor's system requirements. The heap may be of a fixed size or may be expanded as required by the computation and may be contracted if a larger heap becomes unnecessary. The memory for the heap does not need to be contiguous.
JVMS: 2.5.3 HeapThe heap is created on virtual machine start-up. Heap storage for objects is reclaimed by an automatic storage management system (known as a garbage collector); objects are never explicitly deallocated. The Java Virtual Machine assumes no particular type of automatic storage management system, and the storage management technique may be chosen according to the implementor's system requirements. The heap may be of a fixed size or may be expanded as required by the computation and may be contracted if a larger heap becomes unnecessary. The memory for the heap does not need to be contiguous.If a computation requires more heap than can be made available by the automatic storage management system, the Java Virtual Machine throws an OutOfMemoryError.
Hipótesis GeneracionalHipótesis generacional debil
La mayoría de los objetos mueren jovenes
80% - 95% de los objetos en 1MB mueren antes de que se llene el siguiente MB
95% de los objetos Java son de corta vida
Memoria generacional
Perm
Gen
(jdk8
- na
tivo)
Old Gen
Young Gen
Young Gen
Young GenEden
Survivor SpacesFrom To⇄
Allocation
Allocation
Allocation
From To
Allocation
From To
Allocation
To From
Allocation
To From
Allocation
From To
Promotion
From To
No hay espacio suficiente
Promotion
From To
Old Generation
Colectores en Oracle JVM
Serial Garbage Collector
Parallel Garbage Collector
Concurrent Mark-Sweep Garbage Collector
G1 Garbage Collector (Garbage 1srt)
Serial Garbage CollectorCompactación por deslizamiento, con una pausa stop-the-world
Util para ambientes con 1 virtual core o en ambientes donde varias JVMs comparten el mismo hardware
Para Heaps en el orden de MBs
Pausas posiblemente largasApp App AppGC GC
Parallel Garbage Collector
Compactación por deslizamiento, con una pausa stop-the-world
utiliza todos los núcleos disponibles
Alto throughput
Para Heaps en el orden de GBs App App AppGC GC
Concurrent Mark-Sweep Garbage Collector
Diseñado para tener un tiempo de respuesta consistente
Hace gran parte del trabajo de limpiar Old Gen concurrente a la aplicación
Si se acaba el espacio antes de que CMS pueda limpiar, ocurre una SWP y limpia en paralelo
Require un Heap mas grande
App App AppIM RM
SW
G1 Garbage Collector (Garbage 1srt)
G1 Garbage Collector (Garbage 1srt)
G1 Garbage Collector (Garbage 1srt)
G1 Garbage Collector (Garbage 1srt)
G1 Garbage Collector (Garbage 1srt)
G1 Garbage Collector (Garbage 1srt)
Paralelo, concurrente e incremental
Pausas cortas y alto throughput
Divide el heap en regiones
Cada región puede cambiar de rol según se requiera al momento
Remplazo a largo tiempo del CMS, en JDK9 es el GC por defecto
App App AppGC GC
¿Cuándo un Objeto es basura?
Un objeto es elegible para ser colectado cuando desde ningún GC Root de la jvm se puede alcanzar con una referencia fuerte al objeto
Referencia fuerte (Variable en alcance)
GC Root de la jvm
GC Roots de la JVM
Variables locales (stack)
Threads activos
Variables estáticas
Referencias JNIGC Roots
Objetos Alcanzables
Objetos NO Alcanzables
Tipos de Referencias
Fuerte
Suave ( SoftReference )
Debil ( WeakReference )
Fantasma ( PhantomReference )
Ejemplo WeakReferenceWagTask.run Kennel.dogCache
WeakReference
Dog
Tail
Stack Heap
Ejemplo WeakReferenceWagTask.run Kennel.dogCache
WeakReference
Dog
Tail
Stack Heap
El Thread se muere
Ejemplo WeakReferenceKennel.dogCache
WeakReference
Dog
Tail
Heap
Durante un GC
Ejemplo WeakReferenceKennel.dogCache
WeakReference
null
Heap
Después del GC
Problemas comunes (y como evitarlos)
Memory leakpublic void push(Object e) { ensureCapacity(); elements[size++] = e; }
public Object pop() { if (size== 0) throw new EmptyStackException(); return elements[--size]; }
Memory leakpublic void push(Object e) { ensureCapacity(); elements[size++] = e; }
public Object pop() { if (size== 0) throw new EmptyStackException(); return elements[--size]; }
Memory leak
public Object pop() { if (size== 0) throw new EmptyStackException(); Object result = elements[--size]; elements[size] = null; return result; }
Clases miembropublic class MySet<E> extends AbstractSet<E> { ... // otros métodos de la clase public Iterator<E> iterator() { return new MyIterator(); }
private class MyIterator implements Iterator<E> { ... } }
Clases miembropublic class MySet<E> extends AbstractSet<E> { ... // otros métodos de la clase public Iterator<E> iterator() { return new MyIterator(); }
private class MyIterator implements Iterator<E> { ... } }
Clases miembropublic class MySet<E> extends AbstractSet<E> { ... // otros métodos de la clase public Iterator<E> iterator() { return new MyIterator(); }
private class MyIterator implements Iterator<E> { ... } }
static
Otro Memory Leak static Vector vector = new Vector(): ...
for (int n = count-1; n > 0; n--) { vector.removeElementAt(n); } ...
Otro Memory Leak static Vector vector = new Vector(): ...
for (int n = count-1; n > 0; n--) { vector.removeElementAt(n); } ...
>=
Otro Memory Leak
static Vector vector = new Vector(): ...
vector.clear(); ...
Nonlocal Instance Fieldpublic class Storer { private Map<Integer, String> hm = new HashMap<>();
private void doSomething() { // hm sólo se usa aquí hm.put(1, "java"); // … } }
Nonlocal Instance Fieldpublic class Storer { private Map<Integer, String> hm = new HashMap<>();
private void doSomething() { // hm sólo se usa aquí hm.put(1, "java"); // … } }
Referencias olvidadasReader reader = new Reader(); button.addActionListener(reader); try { reader.readSomething(); } catch (IOException e) { // se maneja la excepción } // Ya no se usa reader
Referencias olvidadasReader reader = new Reader(); button.addActionListener(reader); try { reader.readSomething(); button.removeActionListener(reader); } catch (IOException e) { // se maneja la excepción } // Ya no se usa reader
Referencias olvidadasReader reader = new Reader(); button.addActionListener(reader); try { reader.readSomething(); button.removeActionListener(reader); } catch (IOException e) { // se maneja la excepción } // Ya no se usa reader
Referencias olvidadasReader reader = new Reader(); button.addActionListener(reader); try { reader.readSomething(); } catch (IOException e) { // se maneja la excepción } finally { button.removeActionListener(reader); } // Ya no se usa reader
Referencias fuertesclass HashMetaData { private Map<SSLSocket, InetAddress> m = Collections.synchronizedMap( new HashMap<>());
public void storeTempConn(SSLSocket sock, InetAddress ip) { m.put(sock, ip); } pubic void removeTempConn(SSLSocket sock) { m.remove(sock); } }
Referencias fuertesclass HashMetaData { private Map<SSLSocket, InetAddress> m = Collections.synchronizedMap( new WeakHashMap<>());
public void storeTempConn(SSLSocket sock, InetAddress ip) { m.put(sock, ip); } pubic void removeTempConn(SSLSocket sock) { m.remove(sock); } }
Referencias fuertes
class HashMetaData { private Map<WeakReference<SSLSocket>, InetAddress> m = Collections.synchronizedMap( new HashMap<>()); ReferenceQueue queue = new ReferenceQueue();
...
Referencias fuertespublic void storeTempConn(SSLSocket sock, InetAddress ip) { WeakReference<SSLSocket> wr; while((wr = (WeakReference) queue.poll) != null){ //... m.remove(wr); } wr = new WeakReference<>(sock, queue); m.put(wr, ip); } ...
Referencias fuertespublic void storeTempConn(SSLSocket sock, InetAddress ip) { SoftReference<SSLSocket> sr; while((sr = (SoftReference) queue.poll) != null){ //... m.remove(sr); } sr = new SoftReference<>(sock, queue); m.put(sr, ip); } ...
¿ Preguntas ?
BibliografíaEfective Java Second Edition - Joshua Bloch
Java Platform Performance - Steve Wilson, Jeff Kesselman
Java Performance - Charlie Hunt, Binu John
The CERT Oracle Secure Coding Standard For Java - Fred Long, Dhruv Mohindra, Robert C. Seacord,
Dean F Sutherland, David Svoboda