2012-01-27 18 views
10

¿Qué tan grande, en bytes, es una primitiva en caja como java.lang.Integer o java.lang.Character en Java?¿Cuál es el costo de almacenamiento de una primitiva en caja en Java?

Un int tiene 4 bytes, un puntero típico también es de 4 bytes (si no está comprimido por la JVM). ¿El costo de un entero (sin almacenamiento en caché) es 4 bytes + 4 bytes = 8 bytes? ¿Hay más campos ocultos dentro del objeto caja o sobrecarga incurrida en relación con los objetos (es decir, hay un costo general para los objetos que no conozco?).

No me interesan los problemas de almacenamiento en caché. Sé que los enteros dentro de un cierto rango están en caché en la JVM.

Se podría volver a formular la pregunta: ¿Cuál es el factor máximo que se multiplicará en la cantidad de memoria utilizada para los valores encuadrados frente a los valores primitivos?

EDIT: Entiendo que existen múltiples implementaciones de la JVM. ¿Cuál es el costo típico en una implementación típica de HotSpot de 32 bits?

+7

Desde una cierta perspectiva, esta pregunta no tiene respuesta porque la tara en una primitiva en caja no se especifica en ninguna especificación. Puede variar de VM a VM y de plataforma a plataforma. Una plataforma de hardware con memoria etiquetada incluso podría tener cero gastos generales. –

+0

duplicado de [En Java, ¿cuál es la mejor forma de determinar el tamaño de un objeto?] (Http://stackoverflow.com/questions/52353/in-java-what-is-the-best-way-to- determinar el tamaño de un objeto). – DwB

+0

Creo que también podría depender del contexto en el que esté utilizando el int encuadrado y cualquier optimización que esté haciendo el compilador en tiempo de ejecución. –

Respuesta

5

Esta es la implementación definida, por lo que no hay una respuesta específica. Pero debería ser capaz de responderlo por Hotspot.

Lo que necesita saber es: la zona activa siempre alinea los objetos en los límites de 8 bytes. Además hay 2 palabras por encima de cada objeto. [1]

Si ponemos esto juntos obtenemos:

32 bits VM: 4byte enteros + 2 palabras objeto de encabezado = 12bytes. Eso no es múltiplo de 8, por lo que el costo de 1 entero es el siguiente múltiplo de 8: 16byte.

VM de 64 bits: entero de 4 bytes + 2 palabras = 20bytes. Redondeo nuevamente: tamaño de 24 bytes.

El tamaño de una referencia obviamente no se adapta al tamaño de un objeto en sí mismo, excepto si tiene referencias a otros objetos, que no es el caso de un simple envoltorio int. Si así fuera, tendríamos 4 bytes por referencia para 32 bits y 4 bytes para montones < = 32 gb con CompressedOops en JVM modernas (de lo contrario, 8 bytes) para JVM de 64 bits.

[1] Las personas interesadas pueden mirar el código en share/vm/oops/oop.hpp

+1

en aras de la completitud: si el objeto está sincronizado, habrá una estructura nativa sosteniendo el mutex. – bestsss

+0

@bestsss Derecha, ignoró por completo eso. Creo que los bloqueos de peso pesado solo se crean si tenemos un bloqueo disputado (suponiendo un bloqueo sesgado). Si no lo hacemos, y no usamos el código hash del objeto, creo que Hotspot almacena el título en el encabezado del objeto. Entonces, simplemente llamando 'synchronized (foo)' puede no necesariamente asignar memoria. – Voo

+0

sí. Los bloqueos sesgados no previstos no inflan el encabezado si hay una solicitud System.identityHashCode(). Este último se usa (no oficialmente) para evitar el bloqueo sesgado en un objeto seleccionado. (me refiero en su mayoría contento -> a veces utilicé 'Object lock = new Byte (1)' para simplificar la serialización – bestsss

1

Es más que eso.

Cada referencia de objeto tiene una sobrecarga adicional, como una referencia de clase. No solo eso, tu puntero de 4 bytes no es muy preciso. Es una referencia, por lo que es un ID más un puntero, Y ese puntero puede tener 8 bytes si está en una JVM de 64 bits.

También parece haber diferencias en la implementación de VM. La mejor manera de estar seguro de esto sería subirlo en un generador de perfiles.

Mi estimación (Super SWAG) sería. Referencia de objeto 16 bytes (JVM de 64 bits) Referencia de clase 16 bytes valor primitivo 4 bytes (Asumiendo int.) Total. 36 bytes.

EDITAR: Ahora que su JVM de 32 bits especifica mi SWAG sería de 20 bytes usando las mismas operaciones matemáticas anteriores.

+0

No tengo la menor idea de cómo se te ocurren esos números ... mirando mi fuente de Hotspot en 'oop.hpp' también hace yo no soy el más sabio (solo puedo encontrar los 2 punteros usuales) – Voo

0

Sé que esto no responde exactamente a su pregunta sobre el costo de almacenamiento de primitivas en caja, pero tengo la sensación por su pregunta que usted está cuestionando si no su uso de ellos está garantizado.

Aquí es un extracto de Effective Java (2ª edición) por Joshua Bloch que debe ayudar a decidir:

"So when should you use boxed primitives? They have several legitimate uses. The first is as elements, keys, and values in collections. You can’t put primitives in collections, so you’re forced to use boxed primitives. This is a special case of a more general one. You must use boxed primitives as type parameters in parame- terized types (Chapter 5), because the language does not permit you to use primi- tives. For example, you cannot declare a variable to be of type Thread- Local<int>, so you must use ThreadLocal<Integer> instead. Finally, you must use boxed primitives when making reflective method invocations (Item 53).

In summary, use primitives in preference to boxed primitives whenever you have the choice. Primitive types are simpler and faster. If you must use boxed primitives, be careful! Autoboxing reduces the verbosity, but not the danger, of using boxed primitives. When your program compares two boxed primitives with the == operator, it does an identity comparison, which is almost certainly not what you want. When your program does mixed-type computations involving boxed and unboxed primitives, it does unboxing, and when your program does unboxing, it can throw a NullPointerException. Finally, when your program boxes primitive values, it can result in costly and unnecessary object creations."

Espero que ayude.

Cuestiones relacionadas