sorteo - loto java
¿Cuál es el costo de almacenamiento de una primitiva en caja en Java? (3)
¿Qué tan grande, en bytes, es una primitiva en caja como java.lang.Integer
o java.lang.Character
en Java?
Un int
es de 4 bytes, un puntero típico también es de 4 bytes (si no está comprimido por la JVM). ¿El costo para un entero (sin almacenamiento en caché) es 4 bytes + 4 bytes = 8 bytes
? ¿Hay más campos ocultos dentro del objeto box o sobrecarga incurrida en relación con los objetos (es decir, hay un costo general para los objetos que no conozco?).
No estoy interesado en problemas de almacenamiento en caché. Sé que los enteros dentro de un cierto rango están en caché en la JVM.
Uno podría reformular la pregunta: ¿Cuál es el factor máximo a multiplicar en la cantidad de memoria utilizada para los valores encuadrados frente a los valores primitivos?
EDITAR: 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?
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 la misma matemática anterior.
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: Hotspot siempre alinea los objetos en los límites de 8 bytes. Además hay 2 palabras por encima de cada objeto. [1]
Si juntamos esto obtenemos:
VM de 32 bits: entero de 4 bytes + encabezado de objeto de 2 palabras = 12 bytes. 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 = 20 bytes. Redondeo nuevamente: tamaño de 24 bytes.
El tamaño de una referencia, obviamente, no juega en el tamaño de un objeto en sí, 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 ver el código en share/vm/oops/oop.hpp
Sé que esto no responde exactamente a su pregunta sobre el costo de almacenamiento de las primitivas en caja, pero intuyo por su pregunta que está cuestionando si su uso de ellas está justificado o no.
Aquí hay un fragmento de Effective Java (2nd Edition) de Joshua Bloch que debería ayudarte 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.