2012-04-30 11 views
5

Me gustaría saber exactamente el espacio real asignado en memoria para un objeto.Java y tamaño de referencia exacto para objetos, matriz y tipos primitivos

trato de explicar con cierta ejemplo: el uso de un 64 bits JVM, tamaño del puntero debe ser de 8 bytes, por lo que:

  • Object singletest = new Object(); tomarán 8 bytes para hacer referencia al objeto más el tamaño del objeto
  • Object arraytest = new Object[10]; tomarán 8 byte para hacer referencia a la posición en la que se almacena la matriz más 8 * 10 bytes para almacenar la matriz más el tamaño de cada objeto
  • int singleint = new int; se llevará a sólo 2 bytes, porque int es un tipo primitivo
  • int[] arrayint = new int[10]; se llevará a 8 bytes para hacer referencia a la posición y 10 * 2 bytes para los elementos

Por otra parte, esta es la razón por la cual Java permite escribir código como este:

int[][] doublearray = new int[2][]; 
int[0][] = new int[5]; 
int[1][] = new int[10]; 

Lo que realmente sucede es que una matriz producirá una referencia (alias puntero) como un objeto, por lo que realmente no importa el tamaño de la segunda dimensión en el momento de la declaración (y las dimensiones pueden ser diferentes, no hay un vínculo entre ellas) . Entonces el espacio tomado será: una referencia a doublearray (8 bytes), la primera dimensión es simplemente una referencia a la segunda, por lo que otros 8 bytes * 2 (primer tamaño de dimensión) y finalmente 2 bytes * 5 más 2 bytes * 10.

Así, por último, si tienen una clase real de la siguiente manera:

class Test { 
    int a, b; 
    int getA() {return A}; 
    void setA(int a) {this.a = a;} 
    int getB() {return B}; 
    void setB(int b) {this.b = b;} 
} 

cuando llame a una nueva para crear una instancia, un puntero (o el nombre que referencia, porque es Java) de 8 bytes se se puede usar más 2 + 2bytes para almacenar los enteros en la clase.

Las preguntas son: ¿estoy en lo cierto o escribí tonterías? Además, cuando no instalo un objeto pero lo declaro, ¿se asignarán 8 bytes para un uso posterior o no? ¿Y qué pasa si le asigno un valor nulo?

Mientras tanto para el tipo primitivo estoy bastante seguro de que al declarar asignará el espacio solicitado (si declaro un "int i" entonces puedo llamar inmediatamente a i ++ porque no se usa referencia, solo una parte de la memoria está configurada en "0").

He buscado en Internet sin respuesta inteligente ... Sé que escribí muchas preguntas, pero cualquier ayuda será apreciada! (Y tal vez no soy el único interesado)

+0

posible duplicado de [¿Hay una manera simple de obtener el tamaño de un objeto java?] (Http://stackoverflow.com/questions/8775865/is-there-a-simple-way-to-get -the-size-of-a-java-object) –

Respuesta

8

utilizando una JVM de 64 bits, el tamaño del puntero debe ser de 8 bytes,

En realidad es por lo general de 32 bits a menos que tenga un tamaño máximo de almacenamiento dinámico de 32 GB o más montón. Esto se debe a que Java usa referencias, no punteros (y cada objeto está en un límite de 8 bytes, no 1)

La JVM puede cambiar el tamaño de una referencia dependiendo de qué JVM usa y cuál es el tamaño de almacenamiento dinámico máximo.

Objeto singletest = new Object(); tomará 8 bytes para hacer referencia al Objeto más el tamaño del Objeto

El objeto utilizará aproximadamente 16 bytes de Heap. Puede o no usar 4 bytes de pila, pero podría usar un registro.

Objeto arraytest = new Objeto [10];

Esto se utilizan alrededor de 16 bytes para la cabecera, además de 10 veces los tamaños de referencia (alrededor de 56 bytes en total)

int singleint = new int; se llevará a sólo 2 bytes, porque int es un tipo primitivo

int es siempre de 32 bits poco, no se puede crear un new primitiva. Como es teóricamente en la pila, podría usar 4 bytes de pila o solo podría usar un registro.

int [] arrayint = new int [10]; se llevará a 8 bytes para hacer referencia a la posición y 10 * 2 bytes para los elementos

De nuevo es probable que sea del mismo tamaño que los new Object[10] (56 bytes)

int[][] doublearray = new int[2][]; 
int[0][] = new int[5]; 
int[1][] = new int[10]; 

el objeto que no lo haría llamar a un doublearray, ya que podría ser confundida con double[]

Sin embargo, el tamaño es likkely a ser de aproximadamente 16 + 2 * 4 para doublearray y 16 + 5 * 4 + 4 (para relleno) y 16 + 10 * 4.

La memoria asignada en el montón está alineada con un límite de 8 bytes.

Llamo a un nuevo para crear instancias, se usará un puntero (o lo que sea referencia, porque es Java) de 8 bytes más 2 + 2 bytes para almacenar los enteros en la clase.

La referencia está en la pila y, por lo general, no está incluida.

El objeto tiene un encabezado de aproximadamente 16 bytes y los valores int ocupan 2 * 4 bytes.

cuando no una instancia de un objeto, pero yo sólo lo declaro

Java no le permite declarar objetos, sólo primitivas y referencias.

¿Qué ocurre si asigno un valor nulo?

Eso podría cambiar el valor de la referencia, pero de lo contrario no pasa nada.

si declarar un "int i" entonces puedo llamar inmediatamente i ++ porque no se utilizan de referencia, sólo una parte de la memoria se setted en "0"

será utilizado No montón, posiblemente no se usará ninguna pila (posiblemente 4 bytes). Es posible que el compilador JIT elimine el código si no hace nada.

Tal vez no soy el único interesado

... pero no era demasiado miedo de preguntar. ;)

+0

¡Gracias! :) ¡Este es el tipo de respuesta por la que estaba vagando! Estoy anotando cada palabra! :) – pierpytom

+0

PD: Estaba realmente equivocado con "new int", me acabo de dar cuenta de que escribí "new int" de verdad ... confundí el tamaño de 32 bits de int con 16bit, pero "new int" ... – pierpytom

+1

tener un fondo de C++ por casualidad? ;) El hecho de que la JVM de 64 bits pueda usar referencias de 32 bits, y a menudo lo hace, puede sorprender incluso a los desarrolladores experimentados de Java. –

Cuestiones relacionadas