Download as pdf or txt
Download as pdf or txt
You are on page 1of 65

Garbage Collector

Conociendo 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 Heap
The 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 Heap
The 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 Generacional
Hipó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

( jdk8 - nativo)
Old Gen
PermGen

Young Gen
Young Gen
Young Gen
Eden

Survivor Spaces
From⇄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 Collector
Compactació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


App GC App GC App
Pausas posiblemente largas
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 GC App GC App


Concurrent Mark-Sweep Garbage
Collector
SW
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 App IM App RM App
Require un Heap mas grande
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
App GC App GC App
Remplazo a largo tiempo del CMS, en
JDK9 es el GC por defecto
¿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) Objetos NO


Alcanzables
Threads activos
Objetos
Variables estáticas Alcanzables
Referencias JNI
GC Roots
Tipos de Referencias

Fuerte

Suave ( SoftReference )

Debil ( WeakReference )

Fantasma ( PhantomReference )
Ejemplo WeakReference
Stack Heap
WagTask.run Kennel.dogCache

WeakReference

Dog

Tail
Ejemplo WeakReference
Stack Heap
WagTask.run Kennel.dogCache

WeakReference

El Thread se muere
Dog

Tail
Ejemplo WeakReference
Heap
Kennel.dogCache

Durante un GC WeakReference

Dog

Tail
Ejemplo WeakReference
Heap
Kennel.dogCache

Después del GC WeakReference

null
Problemas comunes
(y como evitarlos)
Memory leak
public void push(Object e) {
ensureCapacity();
elements[size++] = e;
}

public Object pop() {


if (size== 0)
throw new EmptyStackException();
return elements[--size];
}
Memory leak
public 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 miembro
public 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 miembro
public 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 miembro
public class MySet<E> extends AbstractSet<E> {
... // otros métodos de la clase
public Iterator<E> iterator() {
return new MyIterator();
}
static
private class MyIterator implements Iterator<E> {
...
}
}
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 Field
public class Storer {
private Map<Integer, String> hm =
new HashMap<>();

private void doSomething() {


// hm sólo se usa aquí
hm.put(1, "java");
// …
}
}
Nonlocal Instance Field
public class Storer {
private Map<Integer, String> hm =
new HashMap<>();

private void doSomething() {


// hm sólo se usa aquí
hm.put(1, "java");
// …
}
}
Referencias olvidadas
Reader reader = new Reader();
button.addActionListener(reader);
try {
reader.readSomething();
} catch (IOException e) {
// se maneja la excepción
}
// Ya no se usa reader
Referencias olvidadas
Reader 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 olvidadas
Reader 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 olvidadas
Reader 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 fuertes
class 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 fuertes
class 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 fuertes
public 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 fuertes
public 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ía
Efective 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

You might also like