Escolar Documentos
Profissional Documentos
Cultura Documentos
escritorios
Manejo de la memoria
Java simplifico mucho respecto al manejo de la memoria, fue la introducción del
manejo de recolector de basura. En java la asignación de datos y objetos en la
memoria ram se maneja de manera automática y el programador se enfoca en
cosas más importantes. Una vez que nuestro programa haya dejado de usar éste
espacio de memoria el recolector de basura detecta este espacio de memoria y los
limpia con el objeto de reutilizarlo.
Vamos a ver que significa cuando hablamos sobre recolector de basura en los
campos deJava. El recolector de basura es la frase que se usa para describir la
administración de memoria automática en Java. Dondequiera que se ejecute un
programa (Ya sea en Java, C, C++, Lisp, Ruby, etc), este usa memoria de
diferentes maneras. Es típico para la memoria crear un stack, un heap, en el caso
de Java crear constant pools y áreas de método. El Heap es la parte de la
memoria donde los objetos de Java viven, y es la única que de cualquier manera
está envuelta en el proceso de recolección de basura.
Así, todo gira en torno a la recolección de basura asegurandose que el Heap tiene
suficiente espacio libre como le sea posible. Cuando el GC se ejecuta, su
propósito es buscar y borrar los objetos que no pueden ser alcanzados. Si
pensamos que un programa en Java es como un ciclo constante de creación de
objetos que se necesitan (los cuales ocupan espacio en el heap), y entonces se
van descargando los objetos que ya no son necesitados, creando nuevos objetos,
descartandolos, y así, la pieza que nos falta para completar el puzzle es el GC.
Cuando se ejecuta, busca todos esos objetos descartados y los borra de la
memoria para que el ciclo de uso de memoria y liberandose pueda continuar.
¿Puede una aplicación Java quedarse sin memoria? Si. El sistema de recolección
de basura intenta eliminar objetos de la memoria cuando no son usados. Sin
embargo, si mantenemos muchos objetos viviendo el sistema puede quedarse sin
memoria. La recolección de basura no puede asegurar que haya suficiente
memoria, solo que la memoria que esté disponible pueda seradministrada de la
manera mas eficiente como sea posible.
Hay otra manera por la cual los objetos pueden convertirse en elegibles para la
recolección, incluso si siguen manteniendo referencias válidas. A este escenario le
llamaremos “Islas de Aislamiento”.
Un ejemplo simple es una clase que tiene una variable de instancia que es una
variable de referencia a otra instancia de la misma clase. Ahora imaginemos que 2
instancias existen y que se refieren la una a la otra. Si todas las otras referencias
de estos 2 objetos fueran removidas, entonces incluso cada objeto mantendría
una referencia válida, no habría manera para cualquier thread vivo de acceder a
estos objetos. Cuando el GC se ejecuta, puede usualmente descubrir cualquier
isla de objetos y removerlos. Como podemos imaginar, tales islas pueden ser
grandes, teóricamente conteniendo cientos de objetos. Examinemos el siguiente
código:
public class Island {
Island i;
public static void main (String[] args){
Island i2 = new Island();
Island i3 = new Island();
Island i4 = new Island();
i2.i = i3; // i2 refiere a i3
i3.i = i4; // i3 refiere a i4
i4.i = i2; // i4 refiere a i2
i2 = null;
i3 = null;
i4 = null;
// Otras operaciones
}
}
Cuando el código alcanza el comentario // Otras operaciones, los 3 objetos Island
(previamente conocidos como i2, i3 y i4) tienen variables de referencia que se
refieren el uno al otro, pero para el mundo exterior han sido establecidos a null.
Estos 3 objetos son elegibles para el GC.
En realidad, es posible solo sugerir a la JVM que realice un GC. Sin embargo, no
hay garantías de que la JVM actualmente elimine todos los objetos que no se usen
de la memoria.
Las rutinas del GC que Java provee son miembros de la clase Runtime. La clase
Runtime es una clase especial que tiene un objeto singular (Singleton) para cada
programa main. El objeto Runtime provee de un mecanismo para comunicarse
directamente con la máquina virtual. Para obtener la instancia de Runtime,
podemos usar el método Runtime.getRuntime(), el cual nos retorna el Singleton.
Una vez que tenemos el Singleton podemos invocar el GC usando el método gc().
Esto no quiere decir que System.gc() sea un método que no sirva de nada (Es
mejor que nada). Simplemente no podemos confiar en que System.gc() libere la
suficiente memoria para que no nos tengamos que preocupar de no quedarnos sin
ella.
Ahora que estamos algo mas familiarizados con el como funciona, vamos a ver un
pequeño experimento para ver si podemos ver los efectos del GC. El siguiente
programa nos permite saber de cuanta memoria dispone la JVM y cuanta memoría
libre tiene. Entonces, crearemos 10.000 objetos Date. Despues de esto, nos dirá
cuanta memoría queda libre y entonces llamaremos al GC (El cual, decidirá si se
ejecuta o no). La memoria libre final resultante debería indicar cuando se ha
ejecutado. Vamos a ver el programa:
public class CheckGC {
public static void main (String[] args){
Runtime rt = Runtime.getRuntime();
System.out.println("Memoria Total de la JVM: " +
rt.totalMemory()); System.out.println("Memoria Antes: " + rt.freeMemory());
Date d = null;
for (int i = 0; i < 10000; i++){
d = new Date();
d = null;
}
System.out.println("Memoria Despues: " + rt.freeMemory());
rt.gc();
System.out.println("Despues del GC: " + rt.freeMemory());
}
}
Como podemos ver si ejecutamos el programa, la JVM decidió cuando usar el GC
para los objetos elegibles. En el ejemplo anterior, le sugerimos a la JVM a realizar
un GC cuando terminamos el bucle, y nos honra con nuestra petición. Este
programa solo tiene un thread siendo ejecutado, por lo que no había nada mas
ejecutandose cuando llamamos al método rt.gc(). Tenemos que tener en mente
que el comportamiento de cuando el gc() es llamado puede ser diferente según las
JVM, por lo que no hay garantías de que los objetos sin uso sean removidos de la
memoria. Lo único que podemos garantizar es que si hay poca memoria, el GC se
ejecutará antes de que se lance la excepción OutOfMemoryException.
Ambiente ejecución Java
RANGO
NOMBRE TIPO OCUPA
APROXIMADO
TIPOS DE Carácter
char 2 bytes ---
DATOS simple
EN JAVA
Valor true o
boolean 1 byte ---
false
Float
Double
Character
Boolean
En caso de cadenas:
Clases en Java
Una clase genera un nuevo tipo de datos en java. Una vez definidos esos datos
entonces lo podemos utilizar para poder crear objetos del tipo declarado.
Una clase es una plantilla de la cual podemos de la cual podemos crear más
objetos, debido a que un objeto es una instancia de una clase, normalmente
utilizaremos objetos (Los objetos son una instancia de una clase).
Palabra new reserva espacio de memoria para el objeto