Está en la página 1de 26

22/9/2019

Tema: Gestión de Almacenamiento

Fundamentos de Lenguajes de Programación


Universidad Nacional de la Patagonia Austral
Unidad Académica Río Gallegos

Introducción
• La gestión de almacenamiento o memoria de una
computadora es una tarea fundamental debido a que la
cantidad de memoria es limitada.
• El sistema operativo es el encargado de administrar la
memoria del sistema y compartirla entre distintos usuarios
y/o aplicaciones.
• El RTS (Run Time System) de un lenguaje de programación
administra la memoria para cada programa en ejecución.
• Cuando se habla de gestión de memoria, se hace referencia a
la gestión de memoria a nivel de programas.

FLP Gestion de Almacenamiento 2

1
22/9/2019

Introducción
• La ejecución de un programa requiere que
diversos elementos se almacenen en la
memoria:
– Código del programa (instrucciones)
– Datos
• Permanentes
• Temporales
– Direcciones para controlar de flujo del
ejecución del programa

FLP Gestion de Almacenamiento 3

Elementos principales que requieren


almacenamiento
• La gestión de almacenamiento abarca muchas áreas.
• Los principales elementos de programas y datos que requieren de
almacenamiento son:
– Segmentos de código para programas de usuarios traducidos
• Son los segmentos de código que representan la forma traducida de los programas
de usuario.
– Programas de sistemas en tiempo de ejecución
• Programas que apoyan la ejecución de los programas de usuario, como rutinas de
biblioteca, intérpretes, etc..
– Estructuras de datos y constantes definidas por el usuario
• Se asignan espacio a todas las estructuras de datos declaradas en programas de
usuario o creadas por ellos.
– Puntos de retorno en subprogramas
• Se debe asignar almacenamiento a la información de control de secuencia
generada internamente, como los puntos de retorno de subprogramas.

FLP Gestion de Almacenamiento 4

2
22/9/2019

Elementos principales que requieren


almacenamiento (continuación)
• Entornos de referencia
– El entorno de referencia (asociaciones de identificadores) durante la ejecución del programa,
puede requerir espacio considerable.
• Temporal en evaluación de expresiones
– La evaluación de expresiones requiere el uso de almacenamiento temporal.
• Temporales en transmisión de parámetros
– Cuando se llama un subprograma, se debe evaluar una lista de parámetros y guardar los
valores resultantes en almacenamiento temporal hasta que se completa la evaluación.
• Buffers de entrada-salida
– Almacenamiento temporal donde se guardan datos entre el momento de la transferencia física
a efectiva de datos.
• Datos diversos del sistema
– En casi todas las implementaciones de lenguajes, se requiere almacenamiento para diversos
datos de sistema: tablas, información de situación para entrada-salida y diversos fragmentos
de información de estado.

FLP Gestion de Almacenamiento 5

Fases gestión de almacenamiento


• Asignación inicial
– Al inicio de la ejecución, cada segmento puede estar asignado o libre. Si esta libre, esta
disponible para asignarse de manera dinámica conforme avanza la ejecución.
• Recuperación
– El almacenamiento que ha sido asignado y usado, y que posteriormente queda
disponible, debe ser recuperado por el gestor de almacenamiento para volver a usarlo.
La recuperación puede ser simple, como en la reubicación de un apuntador de pila, o
compleja, como en la recolección de basura.
• Compactación y nuevos usos
– El almacenamiento recuperado puede estar listo de inmediato para volver a usarse, o
puede requerirse una compactación para construir bloques grandes de almacenamiento
libre a partir de fragmentos pequeños.

FLP Gestion de Almacenamiento 6

3
22/9/2019

Gestión memoria: funcionamiento


• Supongamos que vamos a ejecutar un programa, y en un momento dado
sólo está cargado el sistema operativo en la memoria principal.

FLP Gestion de Almacenamiento 7

Gestión memoria: funcionamiento


• Cuando el sistema operativo ejecuta
el programa, carga el código
ejecutable en una zona libre de la
memoria, y el sistema operativo,
además, reserva:
– Una zona para el código, y otra para los
datos como variables globales y constantes.
– Una zona para las llamadas (stack) que
almacenará los parámetros de las funciones,
las variables locales y los valores de retorno
de las funciones (o métodos).
– Una zona para la gestión dinámica de
memoria (el heap). Es decir, aquella
memoria que se solicita durante la ejecución
del programa.

FLP Gestion de Almacenamiento 8

4
22/9/2019

Gestión memoria: funcionamiento


• Durante la ejecución de un programa, se utilizan varias zonas de memoria
bien diferenciadas para guardar los parámetros, el contexto de la
ejecución, las variables locales, el código, etc.
– La pila de llamadas (stack)
– el área de datos dinámicos o montículo (heap),
– el área de datos estáticos, y
– el área de código.
• El compilador traduce cada función y su contenido a lenguaje máquina.
• Cuando se inicia la ejecución de un programa, el sistema operativo carga
el código ejecutable en una zona de memoria que esté libre, y además,
reserva al menos dos espacios más de memoria para que el programa
pueda ejecutarse, y almacene allí los datos que necesite, son el stack
(o pila de llamadas) y el heap (montículo).

FLP Gestion de Almacenamiento 9

Gestión memoria: funcionamiento


• A partir de este momento, el programa está listo para ser ejecutado.
• El sistema operativo indicará a la CPU que para ejecutarlo debe apuntar
con el registro del puntero de instrucciones (IP, instruction pointer) a la
primera instrucción del código, y que debe apuntar con su puntero de pila
(SP, stack pointer) a la primera dirección del área reservada para pila.
• La gestión del heap y del area de datos suele quedar a cargo del
compilador.
• Todas las aplicaciones tienen un punto de entrada (la función main o
similar).
• Cuando empieza la ejecución, el IP de la CPU apunta a la dirección de este
punto de entrada (main).

FLP Gestion de Almacenamiento 10

5
22/9/2019

Asignación de
Memoria Estática y Dinámica
• A la asignación de memoria para algunos elementos
fijos del programa que es controlada por el
compilador se le llama asignación de memoria
estática.

• A la asignación y posible recuperación de memoria


durante la ejecución de un programa y bajo su
control, se le llama asignación de memoria
dinámica.

FLP Gestion de Almacenamiento 11

GESTION DE MEMORIA ESTATICA Y


DINAMICA

FLP Gestion de Almacenamiento 12

6
22/9/2019

Memoria Estática
• Define la cantidad de memoria necesaria para un
programa durante el tiempo de compilación.
• El tamaño no puede cambiar durante el tiempo de
ejecución del programa.
• Algunos lenguajes de programación utilizan la
palabra static para especificar elementos del
programa que deben almacenarse en memoria
estática.

FLP Gestion de Almacenamiento 13

Memoria Estática
• Elementos que residen en memoria estática:
– Código del programa
– Las variables definidas en la sección principal del
programa, las cuales pueden solo cambiar su contenido no
su tamaño.
– Todas aquellas variables declaradas como estáticas en
otras clases o módulos.
• Estos elementos se almacenan en direcciones fijas
que son relocalizadas dependiendo de la dirección en
donde el cargador las coloque para su ejecución.

FLP Gestion de Almacenamiento 14

7
22/9/2019

Método común de asignación de memoria

Mapa de memoria

Memoria disponible Dirección alta


Para el programa
Dirección baja
Variables estáticas

Código del programa

FLP Gestion de Almacenamiento 15

El stack o pila de ejecución


• Cada subprograma (procedimiento, función,
método, etc.) requiere una representación de
si en tiempo de ejecución.
• Estas representaciones se almacenan en el
stack de ejecución con el fin de controlar el
flujo de ejecución del programa.

FLP Gestion de Almacenamiento 16

8
22/9/2019

Ejemplo

….
public static int factorial (int n){ Cuales elementos del
if (n==0) programa serán
return 1; colocados en memoria
else estática?
return n*factorial(n-1);
} Que elementos se
public static void main (String[] a){ almacenaran en el
int a=5; stack en tiempo de
System.out.println(factorial(a)); ejecución?
}
FLP Gestion de Almacenamiento 17

• Es siempre posible, cuando se diseña un programa,


conocer la cantidad de memoria necesaria para que
este se ejecute correctamente?

FLP Gestion de Almacenamiento 18

9
22/9/2019

Memoria Dinámica
• Define el tamaño del espacio de memoria
necesario para un programa en tiempo de
ejecución.
• El tamaño de los elementos puede cambiar
durante la ejecución del programa.
• Por ejemplo, almacena todos los elementos
definidos con la palabra new en un programa.

FLP Gestion de Almacenamiento 19

Memoria Dinámica
• Las variables dinámicas son aquellas que crecen de
tamaño o se reducen durante la ejecución de un
programa.
• Estas se almacenan en un espacio de memoria
llamado heap o montículo.
• El heap se localiza en la región de memoria que esta
encima del stack.
• Algunos lenguajes de programación permiten que el
programador asigne y desasigne manualmente la
memoria.
• Java utiliza un recolector de basura.

FLP Gestion de Almacenamiento 20

10
22/9/2019

Uso del heap


• Para usar el heap un programa requiere:
– Una o mas variables que refieran el lugar donde se
encuentran las variables dinámicas.
– Un método para obtener memoria (p.e. new)
– Una forma de asignar la dirección de memoria a
alguna variable (identificador)
– Una forma para referirse a la variable dinámica

FLP Gestion de Almacenamiento 21

public class Punto {


Ejemplo
private int x=0;
private int y=0; public class UsaPunto {
public static int totalPuntos =0; public static void main(String[] args){
Punto (int _x, int _y){ Punto punto1= new Punto(2,1);
x=_x; Punto punto2 = new Punto(5,5);
y=_y; Punto punto3 = punto1;
totalPuntos++;
}
public void setx(int _x){ Punto[] puntos = {punto1,punto2};
x= _x; System.out.println(Arrays.toString(puntos));
} System.out.println(“Puntos creados “+ Punto.totalPuntos);
public String toString (){ }
return “(”+x+”,”+y+”)”; }
}
}

punto1 punto3 punto2


Punto
Miembros de x=2 x=5 Miembros
instancia y=1 y=5 de clase totalPuntos = 0
void setx(int _x) void setx(int _x)
Metodos de
String toString () String toString ()
instancia

FLP Gestion de Almacenamiento 22

11
22/9/2019

Liberación de memoria
• La memoria estática se libera cuando el programa
finaliza su ejecución.
• La memoria dinámica se libera de dos formas:
– Explicita. El programador decide cuando un elemento debe
ser eliminado de la memoria. El LP provee mecanismos
para liberación de memoria.
– Implícita. El sistema decide que elementos deben ser
eliminados para recuperar el espacio de memoria que
ocupan. El sistema cuenta con un “recolector de basura”.

FLP Gestion de Almacenamiento 23

The Garbage Collector


• Algunos lenguajes de programación requieren que el programador
mantenga la información de todos los objetos creados en un
programa para que estos puedan ser destruidos cuando ya no son
requeridos en la ejecución.
• Este método para manejar la memoria puede resultar tedioso y
propicio a errores.
• Java permite la creación de tantos objetos como sean necesarios
sin tener que destruirlos explícitamente cuando no son requeridos.
• El medio ambiente de ejecución de Java cuenta con un mecanismo
llamado recolector de basura (garbage collector) que se encarga de
eliminar los objetos cuando ya no existen referencias a ellos.
• El recolector de basura, de manera automática, se ejecuta
periódicamente durante la ejecución de un programa.

FLP Gestion de Almacenamiento 24

12
22/9/2019

GESTION DE MEMORIA EN C

FLP Gestion de Almacenamiento 25

Gestión Memoria en C
• Hasta ahora hemos visto que cada vez que se usa una
variable, se reservar un lugar de la memoria al
comenzar el programa.
• Se indica al compilador cuánta memoria se va usar.
• Por ejemplo, la declaración:
• disco mis_cds[40];
• el compilador reserva espacio para 40 cds.
• Si en realidad solo queremos guardar datos para 2 cds,
se desperdicia mucha memoria.
• Si guarda mucha música, dicho array quedará pequeño.

FLP Gestion de Almacenamiento 26

13
22/9/2019

Gestión Memoria en C
• Por tanto, hay ocasiones en las que no sabemos cuánta memoria vamos a
necesitar hasta que no se ejecuta el programa.
• C++ permite poder reservar memoria según se vaya necesitando, es decir,
en tiempo de ejecución.
• Podremos reservar memoria para almacenar 2 cds, o reservar memoria
para 100 cds si el usuario que ejecuta la aplicación es un adicto a la
música: esto lo sabremos en el momento en que se ejecuta el programa,
no antes.

Ventaja de utilizar memoria dinámica:


• Los programas aprovecharán mejor la memoria de la computadora en el
que se ejecuten, usando sólo lo necesario.

FLP Gestion de Almacenamiento 27

Apuntadores en C++.
• Los apuntadores son variables que almacenan direcciones en
lugar de datos.
• Los apuntadores permiten apuntar hacia distintas localidades
de memoria, por lo que se utilizan para generar memoria
dinámica.
• Los apuntadores pueden ser de cualquier tipo, se declaran
anteponiendo un *:
– int *puntero; //apuntador a un entero
– char *cad; //apuntador a caractér
– void *puntero; //puntero a cualquier tipo de dato

FLP
28 Gestion de Almacenamiento

14
22/9/2019

Aritmética de apuntadores en C++.


• La aritmética de apuntadores significa poder
desplazarse a través de la memoria.

• Sólo se pueden utilizar los operadores +,-, ++, --


y otros operadores de manera indirecta.

• El operador & se utiliza para obtener la


dirección de una variable.

FLP
29 Gestion de Almacenamiento

Memoria estática y dinámica


• Los apuntadores se utilizan para crear
memoria dinámica.

• De manera predeterminada, las variables se


crean con memoria estática en lo que se
conoce como tiempo de ejecución, por eso se
debe de definir un tamaño máximo en los
arreglos.

FLP
30 Gestion de Almacenamiento

15
22/9/2019

Memoria Dinámica
• En C se utiliza la función malloc para pedir
memoria y free para liberarla.

• arreglo = (int *) malloc(N * sizeof(int));


• free(arreglo);

• En Java no existe como tal los punteros pero


se puede utilizar memoria dinámica.
FLP
31 Gestion de Almacenamiento

Memoria Dinámica
• En C++ al igual que Java se utiliza el operador
new para pedir memoria dinámica. De hecho
en Java los arreglos deben crearse con el
operador new:
– int a[5] = new int[5]; //Java
– int a[] = new int[N]; //C++
• delete [] a;

FLP
32 Gestion de Almacenamiento

16
22/9/2019

Memoria Dinámica

• En Java no existe el concepto de liberar


memoria ya que se hace de manera automática
con el recolector de basura.

• La memoria dinámica sirve para crear otros


tipos de ADT más especializados como listas,
pilas, colas, árboles, etc.

FLP
33 Gestion de Almacenamiento

Memoria Dinámica
• Al borrar un elemento se regresa la memoria
que se pidió, por eso es importante liberar la
memoria, ya que si no se hace se pierde ese
pedazo.

• Si se crea memoria dinámica para un objeto se


puede llamar a su constructor para que lo
inicialice.

FLP
34 Gestion de Almacenamiento

17
22/9/2019

Creación y uso de arreglos y objetos


dinámicos en C++. Comparación con
JAVA.
• En Java no existe el concepto de puntero. Se
pueden crear memoria dinámica.

• En objetos al liberar memoria se invoca de


manera automática al destructor en C++ y al
método finalize() y variantes en Java.

FLP
35 Gestion de Almacenamiento

Ejemplo Lenguaje C
• //Memoria Dinamica
• #include <stdio.h>
• #include <stdlib.h> //importante incluir
• //malloc free realloc
• //Malloc sirve para asignar en Mem Dinamica
• //void * malloc(size_t numero_de_bytes)
• //Free sirve para liberar la memoria dinamica
• //Realloc: realocar la memoria
• int main(){
• return 0;
• }

FLP Gestion de Almacenamiento 36

18
22/9/2019

Ejemplo Lenguaje C
• #include <stdio.h> • void * p1 = NULL;
• #include <stdlib.h> //importante recuerden incluir • //Pido espacio en la memoria dinamica
• //malloc free realloc • //con la funcion malloc para un entero
• //Malloc sirve para asignar en Mem Dinamica • p1 = malloc(sizeof(int));
• //void * malloc(size_t numero_de_bytes) • //si quiero hacer cosas con ese espacio
• //Supongamos que quiero guardar un int =3 • //tengo q convertir p1 de (void *) a (int *)
• int main(){ • int * p1_convertido = (int *)p1;
• //En memoria Estatica seria: • //Guardo el numero 3
• //int a; • *p1_convertido= 3;
• //a=3; • //imprimo
• //printf("a:%d",a); • printf("p1 convertido:%d \n",*p1_convertido);
• //En memoria Dinamica: • return 0;
• }

FLP Gestion de Almacenamiento 37

Ejemplo Lenguaje C
• #include <stdio.h>
• #include <stdlib.h> //importante recuerden incluir
• //void * malloc(size_t numero_de_bytes)
• int main(){
• void* p1 = malloc(sizeof(char));
• //si esta llena le memoria dinamica
• //malloc devuelve NULL
• if (p1==NULL){
• printf("Error: La memoria esta llena");
• }
• else{
• printf("Se asigno correctamente p1");
• }
• //Libero el espacio pedido con malloc
• //que seria lo que apunta p1
• free(p1);
• return 0;
• }

FLP Gestion de Almacenamiento 38

19
22/9/2019

GESTION DE MEMORIA EN JAVA

FLP Gestion de Almacenamiento 39

Manejo de Memoria Estatica


• La memoria estatica es la que se reserva al momento de
compilacion.
• Los objetos son creados en ese momento y destruidos al final
del programa.
• Mantiene la misma de localizacion en memoria durante todo
el transcurso del programa.
• Los objetos administrados de este modo son:
Variables Static.
Variables Globales.
Miembros Static de la Clase.
Literales de cualquier tipo.

FLP Gestion de Almacenamiento 40

20
22/9/2019

Características
• Su principal característica es que ocupan solo una casilla de
memoria.
• Dentro de este grupo de datos se encuentra: enteros, reales,
caracteres, boléanos, enumerados y subrangos (los últimos no
existen en algunos lenguajes de programación).
• El inconveniente de la reserva estática es que la cantidad de
memoria se reserva siempre antes de conocer los datos
reales.
• Como consecuencia de esta condición no podrán
almacenarse en memoria estática:
– Los objetos correspondientes a procedimientos o funciones recursivas.
– Las estructuras dinámicas de datos tales como listas, árboles, etc.

FLP Gestion de Almacenamiento 41

Ejemplo
class ejemplo1{ En el ejemplo 1 se muestra la
public static void main (String[] args) { declaracion de un arreglo y la
int[] Numeros= {1,2,3,4,5};
declaracion de la variable global
for (int i=0; i<5;i++)
System.out.println(Numeros[i]); dentro del for. El metodo main
} es static.
}

class ejemplo2{ En el ejemplo 2 se muestra la


static int Funcion(int p, int q){ declaracion static de una
return (p+q); funcion en la cual es ejecutada
}
al enviarle dos parametros que
public static void main(String[] args){
int Resultado=Funcion(7,2); son literales numericas.
System.out.println(Resultado);
}
}

FLP Gestion de Almacenamiento 42

21
22/9/2019

Consideraciones
• En resumen, el inconveniente de utilizar memoria static,
aunque es mas facil de programar, es que la cantidad de
memoria se reserva antes de conocer los datos completos del
problema, lo que a veces lleva a reservar un maximo de
memoria que en la mayoria de las veces no se va a necesitar.

FLP Gestion de Almacenamiento 43

Funcionamiento
• Una aplicación Java está pensada para que pueda ejecutarse en cualquier
plataforma.
• Java no se ejecutan directamente sobre el hardware, sino sobre una capa
intermedia llamada Java Virtual Machine (JVM).
• Cuando se arranca un proceso Java, el sistema operativo reserva una
porción de memoria de la JVM que permite que se ejecute dicho proceso.
• Esquema memoria de Java:

FLP Gestion de Almacenamiento 44

22
22/9/2019

Funcionamiento
• En la memoria permanente (Perm) se almacena todo el código
ejecutable cuyo tamaño no va a variar durante la ejecución del
proceso.
• El Stack es otra zona de la memoria permanente (Perm) en la que se
almacenan las variables locales de cada función o método que se
ejecuta, parámetros o valores de retorno, y direcciones de memoria
para retornar.
• Cuando finaliza la ejecución de la función, las variables locales se
liberan y dejan de ocupar memoria.
• Importante: el stack tiene un tamaño fijo que se asigna al comienzo de
la ejecución del proceso y depende de la plataforma donde se esté
ejecutando. Si se llena el stack, aparece el error StackOverflowError.

FLP Gestion de Almacenamiento 45

Funcionamiento
• En el stack también se almacenan referencias a otros
objetos almacenados en la memoria y esto es clave para
liberarlos.
• El Heap es la zona de memoria dinámica cuyo tamaño es
desconocido al arrancarse la aplicación.
• En el heap se pueden crear y destruir objetos en tiempo de
ejecución.
• El heap se estructura de la siguiente manera:
– Young Generation: Se almacenan los nuevos objetos que se van creando en la
aplicación.
– Tenured Generation: Se almacenan objetos antiguos.
– Perm Generation: Se almacenan las clases y constantes.

FLP Gestion de Almacenamiento 46

23
22/9/2019

Ejemplo funcionamiento:
stack y el heap
• Ejemplo :
class Alumno {
public static void main(String[] args) {
Alumno Jose;
Jose = new Alumno();
}
}

• Cuando se ejecuta, en la zona de memoria


Stack se almacena la variable local Jose, que
es una referencia del tipo Alumno.
• Luego, se crea el objeto de tipo Alumno en
el heap y se le asigna la referencia Jose. Es
decir, en la referencia Jose almacenada en
Si quisiéramos crear un nuevo
el stack, está apuntando al objeto
objeto en el Heap, pero no hay
Alumno creado en el heap.
suficiente memoria, se obtiene el
error OutOfMemoryException.

FLP Gestion de Almacenamiento 47

Ejemplo Heap
• Por ejemplo, clase Fecha.
class Fecha {
private int dia ;
private int mes;
private int anio;
}
• Luego se crea 2 objetos de la clase Fecha ( objetos f1 y f2) y se
asigna mismos datos a f1 y f2 .
• Por lo tanto ,se realizan 2 referencias a la misma posición de
memoria

FLP Gestion de Almacenamiento 48

24
22/9/2019

Ejemplo Heap

FLP Gestion de Almacenamiento 49

Garbage Collector

• Para liberar objetos en memoria, Java cuenta con un sistema


llamado Garbage Collector.
• El algoritmo del Garbage Collector liberará de la memoria
todos los objetos que no están referenciados desde el stack.
• El Garbage Collector no se está ejecutando constantemente
sino cada cierto intervalo de tiempo.
• También es posible forzar su ejecución mediante código, a
través de:
– System.gc();
– Runtime.getRuntime().gc();

FLP Gestion de Almacenamiento 50

25
22/9/2019

Gestion de almacenamiento
• Fin de clase

FLP Gestion de Almacenamiento 51

Próximas clases
• Clases prácticas:
– 23, 24 y 26/09
• Parcial 1:
• Lunes 30/9
• Clase teórica:
– Martes 1/10/19: Control de secuencia

FLP Gestion de Almacenamiento 52

26

También podría gustarte