Bienvenidos sean a este post, hoy hablaremos sobre un tema particular como es manejar los datos en la memoria.
Si bien ya mencionamos en este post cuales son las variables de referencia, en el caso de hoy explicaremos como es que se trabaja con la memoria tanto los objetos como los arrays porque no dejan de ser variables de tipo de referencia, para ello vamos a revisitar a las variables.
Cuando hicimos nuestro primer proyecto declaramos (no definimos) nuestras variables, despues fuimos definiendola a medida que ibamos necesitandolas, en este caso en particular tambien no le asignamos ningun modificador de acceso simplemente las declaramos y dejamos que el lenguaje asigne el acceso de manera predeterminada, es decir que no sea restringida para ninguna parte del programa, pero porque las declaramos por fuera de onCreate y no dentro de este metodo? Si recuerdan cuando hablamos de variables dijimos que tienen principalmente dos entornos o dos rangos:
- Locales
- Globales
Siempre las variables van a tener el alcance en donde la definimos, se considera locales a las que se declaran dentro de un metodo o un bloque condicional porque la variable creada en ese entorno morira cuando se termine el metodo o el condicional en cambio las globales son aquellas que pueden ser alcanzadas por todos los componentes del programa, por ejemplo nosotros al declararlas al comienzo de la clase hacemos que todos los metodos dentro de la misma puedan acceder a esas variables ya sea para modificarlas o para recuperar la informacion en cambio si la hubieramos declarado dentro de onCreate una vez terminada la creacion del programa estas hubieran desaparecido de la memoria lo cual generara un error si hubieramos querido acceder a algunas de ellas.
Nota: Igualmente el Android Studio nos hubiera notificado que la variable no puede ser alcanzada.
En nuestros siguiente proyectos al momento de declarar nuestras variables/objetos siempre fueron con el modificador private para indicarle al programa que dichos elementos son solamente para la clase donde fueron declarados pero tambien creamos metodos de tipo getter para poder obtener dichos objetos, con esto y lo que se denomina rango (scope) podemos pasar a nuestro siguiente tema.
El Stack y el Heap
Al igual que ocurre cuando usamos Java en cualquier dispositivo la maquina virtual dentro del Android se encarga del manejo de la memoria para nuestras aplicaciones, permitiendo tener todos nuestros objetos bien ubicados en la misma, las variables que declaramos e iniciamos son alojados en una seccion de la memoria llamada Pila (Stack), en cambio el Monton (heap) sera el lugar donde almacenaremos todas las variables de tipo de referencia, en este caso seran los objetos de las clases creados en nuestro programa, para hacer una analogia (no de tanto acertada) seria compararlo con un galpon, donde la Pila (stack) sera una seccion de nuestro galpon donde podremos manejar todos los datos de la mejor manera, en cambio el monton (heap) va a ser otra seccion de nuestro galpon mucho mas amplia pero toda dividida en estantes, cajones, cajas y todo aquello que nos resulte util para almacenar nuestros elementos que no seran otra cosa mas que los objetos (con sus respectivas estructuras), arrays, variables de tipo de referencia, en fin todo aquello que no ira a la pila pero cual sera el inconveniente con esto? Es que no tenemos un acceso directo a los mismos sino en realidad tendremos una direccion de memoria de la ubicacion de dichos elementos, es decir que cuando nosotros usamos el operador de punto en realidad le solicitamos a DalVik (la maquina virtual) que ejecute la tarea en la ubicacion especificada que se encuentra almacenada en la referencia (direccion de memoria), si esto te parece muy inapropiado a continuacion veremos el porque.
Tanto la pila como el monton son forzados por la arquitectura de nuestro equipo pero Java actua como intermediario para ayudarnos a manejar la memoria, como mencionamos anteriormente la DalVik mantiene un seguimiento de todos nuestros objetos por nosotros y los almacena en la seccion de nuestro galpon llamado monton, y a su vez periodicamente mirara en la pila y comparara las referencias a los objetos, y cuando encuentre alguno sin referencia lo destruira o como se denomina en Java recolecta la basura. Tratemos de imaginarnos que existe un camion recolector de basuras muy preciso que se mueve a traves de todo nuestro monton, mirando los objetos para ver si poseen referencias, no posee una referencia lo transforma en basura porque despues de todo si no tiene una referencia tampoco nos servira para nada, esto nos ayuda a que nuestras aplicaciones corran de manera mas fluida gracias a que se libera memoria que no se usa. Sin embargo, tambien tiene un lado un negativo o una contra, y esta es que el colector de basura tambien consume tiempos de proceso y este no tiene conocimiento de las partes criticas de tiempo de nuestros juegos como son el bucle del juego, entonces puede ser una potencial causa de que nuestro juego corra mas lento.
Ahora que sabemos cual es uno de los inconvenientes que podemos tener con nuestro colector de basura debemos asegurarnos que no ejecutemos un disparador del colector de basura durante las partes criticas del juego, para entender este concepto vamos a mirar la siguiente variable:
algunaVariable = new AlgunaClase();
Definimos esta variable con un nuevo objeto y luego esta se va del rango, pasa a ser destruido ocasionando que se llame al colector de basura, inclusive aunque esto no pase inmediatamente sabemos que en algun momento pasara y no podremos evitarlo, esto es algo que tendremos que tener en mente a la hora de planear nuestros proximos juegos, para resumir un poco lo visto hasta ahora:
- Las variables locales son declaradas dentro de un metodo, se almacenan en la pila y solo son visibles dentro del metodo
- Las variables globales (o miembros) se almacenan en el monton y puede ser referenciada siempre y cuando haya una referencia y el modificador de acceso lo permita.
Veamos algunas de los temas cubiertos en este post:
- Nuestro codigo no borra los objetos sino que es una tarea de la virtual, este evalua cuando es el momento apropiado y usualmente es cuando no tiene una referencia.
- Las variables locales y los metodos estan en la pila (stack), y las variables locales son unicamente accedidas dentro del metodo donde fueron declaradas
- Las variables/instancias de las clases son creadas en el monton (heap) con sus respectivos objetos pero la referencia a dicho objeto se almacena en una variable local en la pila
- Esto nos permite tener un mejor control de la pila, esto nos permite usar los objetos del monton pero solo por referencia
- El monton es mantenido por el colector de basuras
- Un objeto es recolectado cuando no existe una referencia a la misma, es decir cuando removemos una variable local o una instancia desde la pila hace propenso a que el objeto sea valido para la recoleccion, la maquina virtual decide cuando es el momento correcto para hacerlo (usualmente es pronto) para limpiar memoria y evitar que nos quedemos sin la misma
Esto es todo lo que necesitamos saber sobre como trabaja la recoleccion de basura en la memoria, en general se explica pero como podran darse cuenta nosotros no intervenimos en ningun momento pero es bueno saber como Java se encarga de manejar la memoria por nosotros y porque es importante saber la diferencia entre las variables locales y globales.
En resumen, hoy hemos ahondado un poco mas en como las variables acceden a la memoria, como esta dividida, en que parte de la memoria son asignadas dependiendo del tipo, como trabaja la pila, como trabaja el monton, quien mantiene limpio el monton, cuales son los beneficios de trabajar de esta forma, las contras que nos puede ocasionar y como es la mejor forma de trabajarlo, espero les haya sido util sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.
Tengo un Patreon donde podes acceder de manera exclusiva a material para este blog antes de ser publicado, sigue los pasos del link para saber como.

Tambien podes donar
Es para mantenimiento del sitio, gracias!
$1.00