Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Informatica
Informatica
La memoria RAM
Los circuitos digitales únicamente pueden procesar datos representados con ceros
y unos, pero para ello deben estar almacenados en otro circuito que permita a su
vez su modificación. En el contexto de un ordenador este dispositivo suele ser la
memoria RAM (random access memory), un circuito que contiene en su interior
una tabla que almacena información en cada uno de sus compartimentos.
Como toda tabla, es preciso saber dos de sus dimensiones: el tamaño de cada uno
de sus elementos, y el número de elementos de los que dispone. Actualmente, las
memorias convencionales almacenan la información en elementos de tamaño 1
byte. Por lo tanto una memoria se puede ver como una tabla que contiene un
determinado número de bytes. Los elementos de esta tabla están numerados con
números naturales comenzando por el cero. El número correspondiente a cada
una de los elementos se denomina “dirección de memoria” y se suele representar
de forma abreviada por el símbolo “@”. Al conjunto de números que representan
las direcciones de una memoria se le denomina su “espacio de direcciones”.
La figura 3.1 ilustra la estructura, contenido y direcciones de una memoria RAM.
La memoria RAM estática o SRAM es un circuito que una vez que se escribe un
dato en una de sus celdas lo mantiene intacto mientras el circuito reciba voltaje.
En cuanto el voltaje desaparece, también lo hace la información. La celda de
dicha memoria está compuesta por alrededor de seis transistores conectados de
forma similar a un registro. El tiempo de lectura de una posición de memoria
compuesta por ocho celdas suele ser del orden de decenas de nanosegundos (1
nanosegundo son 10-9 segundos).
Al ser la memoria un circuito digital, todos sus datos deben ser codificados
igualmente con ceros y unos y esto incluye a los parámetros que reciben las
operaciones de lectura y escritura. El dato a leer o escribir es un byte y por tanto
ya está codificado en binario. Las direcciones también deben estar codificadas en
binario, y como son números naturales (son positivos y comienzan por cero) la
codificación utilizada es base dos.
La lectura de un dato consiste en enviar a la memoria los bits que codifican una
dirección, y la memoria devuelve ocho bits. La operación de escritura consisten
en enviar a la memoria los bits que codifican una dirección y ocho bits de datos,
y éstos últimos se almacenan en la posición especificada.
Debido a esta relación entre los bits que codifican una dirección y el número de
elementos, las memorias suelen tener un tamaño potencia de 2. El coste de incluir
un número determinado de bits hace que se aprovechen todas sus combinaciones.
Símbol
Prefijo Potencia
o
kilo K 210
mega M 220
giga G 230
tera T 240
peta P 250
exa E 260
zetta Z 270
yotta Y 280
Tamañ
Tipo Contiene Rango
o
boolea
true, false 1 bit
n
byte Entero 8 bits [-128, 127]
char Caracter Unicode 16 bits [0, 65535]
short Entero 16 bits [-32768, 32767]
int Entero 32 bits [-2147483648, 2147483647]
[-9223372036854775808,
long Entero 64 bits
9223372036854775807]
float IEEE-754 Coma Flotante 32 bits [±1.4012985E-45, ±3.4028235E+38]
Tamañ
Tipo Contiene Rango
o
[±4.94065645841246544E-324,
double IEEE-754 Coma Flotante 64 bits
±1.7976931348623157E+308]
La regla para almacenar datos en memoria es utilizar tantos bytes como sean
necesarios a partir de una dirección de memoria. En adelante, la posición de
memoria a partir de la cual está almacenado un dato se denominará su dirección
de memoria. De forma análoga, cuando se dice que un dato está en una posición
de memoria lo que significa es que está almacenado en esa posición y las
siguientes que se precisen.
Los valores booleanos, a pesar de ser los más sencillos, no son los más fáciles de
almacenar. La memoria permite el acceso a grupos de 8 bits (1 byte) por lo que
almacenar un único bit significa utilizar una parte que no es directamente
accesible sino que requiere procesado adicional. Por este motivo se intenta
almacenar varios booleanos juntos y de esta forma maximizar la información
contenida en un byte. Esta estrategia se utiliza cuando es fácil saber la posición
de un booleano dentro del byte. En el caso de que esto no sea posible, se utiliza
un byte para almacenar un único bit, con lo que los 7 bits restantes se
desperdician. La figura 3.5 muestra estas dos posibles situaciones.
La memoria almacena un byte en cada una de sus posiciones que a su vez tiene
una dirección única. El funcionamiento de la memoria está totalmente definido
mediante esta estructura. Sin embargo, cuando la memoria forma parte del
conjunto de un ordenador, el tiempo que tarda en realizar una operación es
mucho mayor comparado con el que tarda el procesador en ejecutar una
instrucción. En otras palabras, los accesos a memoria requieren tanto tiempo que
retrasan la ejecución de las instrucciones del procesador.
Pero para manipular tablas de datos no sólo basta con almacenar los elementos en
posiciones consecutivas. Considérese el siguiente ejemplo. Se dispone de una
tabla de enteros y se debe calcular la suma total de sus elementos. Para ello se
comienza sumando el primer elemento, a él se le suma el segundo, a este
resultado el tercero, y así sucesivamente. Pero ¿cómo se sabe que se ha llegado al
último elemento? Para cualquier tabla, además de la dirección de comienzo y el
tamaño de sus elementos, es preciso saber el número de elementos que contiene.
Existen dos mecanismos para saber cuántos elementos contiene una tabla. El
primero de ellos consiste en depositar como último elemento, un valor que
denote el final. Por ejemplo, considérese una tabla de letras que almacena una
frase. Cada letra se almacena con su codificación en ASCII (ver sección 2.8.1),
por lo que cada letra ocupa un byte. Al final de la tabla se incluye un byte con
valor 0 que está reservado específicamente en ASCII para codificar el final de
una secuencia de letras. Para recorrer todos los elementos de esta tabla basta con
escribir un bucle que se detenga cuando encuentre el valor cero.
Para implementar este mecanismo no sólo toda tabla en Java debe tener
almacenado su tamaño sino que cada acceso va precedido de la comprobación del
valor del índice. Se necesita, por tanto, un mecanismo que almacene los datos de
una tabla y su tamaño de forma compacta y que además permita una eficiente
comprobación de los accesos a sus elementos.
La solución en Java consiste en almacenar el tamaño de una tabla junto con sus
elementos en posiciones consecutivas de memoria. De entre todas las
posibilidades de organizar estos datos, la más lógica es poner el tamaño en las
primeras posiciones de memoria seguido de los elementos. La figura
3.14 muestra cómo se almacena en memoria una tabla de seis enteros de 32 bits
en formato little endian a partir de la posición 0x100.
Para ordenar los strings hay dos opciones, o se manipulan todos los caracteres de
cada uno de ellos, o se manipulan sus direcciones de comienzo. Es decir, en lugar
de tener los strings ordenados alfabéticamente y almacenados en posiciones
consecutivas de memoria, se almacenan por orden las direcciones de memoria de
comienzo de cada string y se ordenan en base a las letras que contienen. Esta
estructura se ilustra en la figura 3.18.
La ordenación los strings se puede realizar sin mover ninguna de las letras en
memoria. La tabla resultante contiene en cada uno de sus elementos una
indirección a un string, es decir, la dirección en la que se encuentra el string
pertinente. Para imprimir los strings en orden alfabético se itera sobre los
elementos de la tabla y mediante doble indirección se accede a las letras de cada
string.
Líne
Código
a
1 Dato obj1, obj2;
2 obj1 = new Dato();
3 obj1.valor = 3;
4 obj2 = obj1;
5 obj2.valor = 4;
6 System.out.println(obj1.valor)
Líne
Código
a
1 Dato2 obj2;
2 obj2 = new Dato2();
3 obj2.c1 = new Dato();
4 obj2.c1.valor = 4;