Perché l'overhead durante l'allocazione di oggetti / matrici in Java?


9

Quanti byte occupa un array in Java? Supponiamo che sia una macchina a 64 bit e supponga anche che ci siano N elementi in un array, quindi tutti questi elementi occuperebbero 2 * N, 4 * N o 8 * N byte per diversi tipi di array.

E una lezione a Coursera afferma che occuperebbe 2 * N + 24, 4 * N + 24 o 8 * N + 24 byte per un array di elementi N e i 24 byte sono chiamati overhead, ma non hanno spiegato perché l'overhead è necessario.

Inoltre gli oggetti hanno un sovraccarico, che è di 16 byte.

Cosa sono esattamente queste spese generali? In cosa consistono questi byte 24/16?

Inoltre, queste spese generali esistono solo in Java? Che ne dici di C, C ++ e Python?



1
@Gnijuohz: Vuoi dire: di quali dati è composto questo overhead?
FrustratedWithFormsDesigner,

@YannisRizos: Penso che l'OP voglia sapere cosa c'è effettivamente in quei 24 byte, per gli array.
FrustratedWithFormsDesigner,

@FrustratedWithFormsDesigner Ah, sembra una migliore interpretazione della domanda rispetto alla mia.
yannis,

@YannisRizos mi dispiace per il mio cattivo atteggiamento. Ma quando pubblichi quel link non posso fare a meno di pensare che sia una sorta di sarcasmo. Troppo sulla difensiva, immagino.
Gnijuohz,

Risposte:


16

Ogni oggetto Java ha un'intestazione che contiene informazioni importanti per la JVM. Il più importante è un riferimento alla classe dell'oggetto (una parola macchina), e ci sono alcuni flag usati dal garbage collector e per gestire la sincronizzazione (poiché ogni oggetto può essere sincronizzato su) che occupa un'altra parola macchina (usando parole parziali sarebbe essere cattivo per le prestazioni). Quindi sono 2 parole, che sono 8 byte su sistemi a 32 bit e 16 byte su 64 bit. Gli array necessitano inoltre di un campo int per la lunghezza dell'array, ovvero altri 4 byte, possibilmente 8 su sistemi a 64 bit.

Come per altre lingue:

  • C non ha oggetti, quindi ovviamente non ha intestazioni di oggetti, ma può avere un'intestazione su ogni pezzo di memoria allocato separatamente.

  • In C ++, non hai garbage collection e non puoi usare oggetti arbitrari per la sincronizzazione, ma se hai classi con metodi sovrascritti, ogni oggetto ha un puntatore alla sua vtable, proprio come il riferimento dell'oggetto Java alla sua classe. Se si utilizzano i puntatori intelligenti che eseguono la garbage collection, hanno bisogno di dati di pulizia.

  • Non so di Python, ma sono abbastanza sicuro che abbia anche bisogno di un riferimento alla classe e di informazioni sulle pulizie per il garbage collector.


Al momento in OpenJDK è in corso un lavoro per ridurre le dimensioni delle intestazioni degli oggetti, piccoli ma importanti passaggi :-)
Martijn Verburg,

In C ++, solo le classi polimorfiche richiedono vtables. std::pair<int, float>è una classe semplice che non ha bisogno di una vtable. Di conseguenza, potrebbe adattarsi molto bene a 8 byte. Inoltre, i puntatori intelligenti non devono effettivamente aggiungere le pulizie. Un chiaro contro-esempio è std::unique_ptr<T>, che in genere è grande quanto il raw T*(unique_ptr ovviamente non fa GC).
MSalters il

4
C ha anche un overhead, ogni mallocblocco di memoria allocato necessita di un'intestazione che freepoi utilizza.
citato il

Almeno una libreria malloc che conosco utilizza un'intestazione di 8 byte su sistemi a 32 bit (che è una lunghezza di 4 byte racchiusa tra due serie di valori sentinella a 2 byte, IIRC).
Donal Fellows,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.