¿Por qué la sobrecarga al asignar objetos / matrices en Java?

9

¿Cuántos bytes ocupa una matriz en Java? Suponga que es una máquina de 64 bits y también asuma que hay N elementos en una matriz, por lo que todos estos elementos ocuparían 2 * N, 4 * N u 8 * N bytes para diferentes tipos de matriz.

Y una conferencia en Coursera dice que ocuparía 2 * N + 24, 4 * N + 24 u 8 * N + 24 bytes para una matriz de elementos N y los 24 bytes se denominan sobrecarga, pero no explicaron por qué la sobrecarga es necesario.

También los objetos tienen gastos generales, que son 16 bytes.

¿Qué son exactamente estos gastos generales? ¿De qué están compuestos estos 24/16 bytes?

Además, ¿estos gastos generales solo existen en Java? ¿Qué tal C, C ++ y Python?

Gnijuohz
fuente
2
Echa un vistazo: stackoverflow.com/a/258150/1029272
Deco
1
@Gnijuohz: ¿Quiere decir: de qué datos se compone esta sobrecarga?
FrustratedWithFormsDesigner
@ YannisRizos: Creo que el OP quiere saber qué hay realmente en esos 24 bytes, para matrices.
FrustratedWithFormsDesigner
@FrustratedWithFormsDesigner Ah, eso parece ser una mejor interpretación de la pregunta que la mía.
Yannis
@YannisRizos perdón por mi mala actitud. Pero cuando publicas ese enlace no puedo evitar pensar que es algún tipo de sarcasmo. Demasiado a la defensiva, supongo.
Gnijuohz

Respuestas:

16

Cada objeto Java tiene un encabezado que contiene información importante para la JVM. Lo más importante es una referencia a la clase del objeto (una palabra de máquina), y el recolector de basura utiliza algunos indicadores y para administrar la sincronización (ya que cada objeto se puede sincronizar) que toma otra palabra de máquina (usar palabras parciales ser malo para el rendimiento). Eso son 2 palabras, que son 8 bytes en sistemas de 32 bits y 16 bytes en 64 bits. Las matrices además necesitan un campo int para la longitud de la matriz, que son otros 4 bytes, posiblemente 8 en sistemas de 64 bits.

En cuanto a otros idiomas:

  • C no tiene objetos, por lo que, por supuesto, no tiene encabezados de objeto, pero puede tener un encabezado en cada pieza de memoria asignada por separado.

  • En C ++, no tiene recolección de basura y no puede usar objetos arbitrarios para la sincronización, pero si tiene clases con métodos anulados, cada objeto tiene un puntero a su vtable, al igual que la referencia del objeto Java a su clase. Si utiliza punteros inteligentes que recogen basura, necesitan datos de limpieza.

  • No sé acerca de Python, pero estoy bastante seguro de que también necesita una referencia a la clase e información de limpieza para el recolector de basura.

Michael Borgwardt
fuente
Actualmente se está trabajando en OpenJDK para reducir el tamaño de los encabezados de objetos, pasos pequeños pero importantes :-)
Martijn Verburg
En C ++, solo las clases polimórficas necesitan vtables. std::pair<int, float>es una clase simple que no necesita una vtable en absoluto. Como resultado, puede muy bien caber en 8 bytes. Además, los punteros inteligentes en realidad no necesitan agregar limpieza. Un claro contraejemplo es std::unique_ptr<T>, que generalmente es tan grande como el raw T*(unique_ptr, por supuesto, no hace GC).
MSalters
44
C también tiene una sobrecarga, cada mallocbloque de memoria asignado necesita un encabezado que freeluego utiliza.
herby
Al menos una biblioteca malloc que conozco utiliza un encabezado de 8 bytes en sistemas de 32 bits (que es una longitud de 4 bytes entre corchetes por dos conjuntos de valores centinela de 2 bytes, IIRC).
Donal Fellows