Documentos de Académico
Documentos de Profesional
Documentos de Cultura
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.
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
2
22/9/2019
3
22/9/2019
4
22/9/2019
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.
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.
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.
7
22/9/2019
Mapa de memoria
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
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.
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.
10
22/9/2019
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”.
12
22/9/2019
GESTION DE MEMORIA EN C
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.
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.
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
FLP
29 Gestion de Almacenamiento
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.
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
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.
FLP
34 Gestion de Almacenamiento
17
22/9/2019
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;
• }
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;
• }
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;
• }
19
22/9/2019
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.
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.
}
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.
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:
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.
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.
23
22/9/2019
Ejemplo funcionamiento:
stack y el heap
• Ejemplo :
class Alumno {
public static void main(String[] args) {
Alumno Jose;
Jose = new Alumno();
}
}
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
24
22/9/2019
Ejemplo Heap
Garbage Collector
25
22/9/2019
Gestion de almacenamiento
• Fin de clase
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
26