Pourquoi la surcharge lors de l'allocation d'objets / tableaux en Java?

9

Combien d'octets un tableau occupe en Java? Supposons que c'est une machine 64 bits et supposons également qu'il y ait N éléments dans un tableau, donc tous ces éléments prendraient 2 * N, 4 * N ou 8 * N octets pour différents types de tableau.

Et une conférence à Coursera dit qu'il occuperait 2 * N + 24, 4 * N + 24 ou 8 * N + 24 octets pour un tableau d'éléments N et les 24 octets sont appelés surcharge, mais n'a pas expliqué pourquoi la surcharge est nécessaire.

Les objets ont également des frais généraux, qui est de 16 octets.

Quels sont exactement ces frais généraux? De quoi sont composés ces 24/16 octets?

De plus, ces frais généraux existent-ils uniquement en Java? Que diriez-vous de C, C ++ et Python?

Gnijuohz
la source
1
@Gnijuohz: Vous voulez dire: de quelles données est composé ce surcoût?
FrustratedWithFormsDesigner
@YannisRizos: Je pense que l'OP veut savoir ce qu'il y a réellement dans ces 24 octets, pour les tableaux.
FrustratedWithFormsDesigner
@FrustratedWithFormsDesigner Ah, cela semble être une meilleure interprétation de la question que la mienne.
yannis
@YannisRizos désolé pour ma mauvaise attitude. Mais quand vous postez ce lien, je ne peux pas m'empêcher de penser que c'est une sorte de sarcasme. Trop défensif, je suppose.
Gnijuohz

Réponses:

16

Chaque objet Java a un en-tête qui contient des informations importantes pour la JVM. Le plus important est une référence à la classe de l'objet (un mot machine), et il y a quelques drapeaux utilisés par le garbage collector et pour gérer la synchronisation (puisque chaque objet peut être synchronisé) qui prend un autre mot machine (utiliser des mots partiels serait être mauvais pour la performance). Cela représente donc 2 mots, soit 8 octets sur les systèmes 32 bits et 16 octets sur 64 bits. Les tableaux ont en outre besoin d'un champ int pour la longueur du tableau, qui est encore 4 octets, éventuellement 8 sur les systèmes 64 bits.

Comme pour les autres langues:

  • C n'a pas d'objets, donc bien sûr il n'a pas d'en-têtes d'objet - mais peut avoir un en-tête sur chaque morceau de mémoire alloué séparément.

  • En C ++, vous n'avez pas de récupération de place et ne pouvez pas utiliser d'objets arbitraires pour la synchronisation, mais si vous avez des classes avec des méthodes substituées, chaque objet a un pointeur vers sa table virtuelle, tout comme la référence de l'objet Java à sa classe. Si vous utilisez des pointeurs intelligents qui effectuent la collecte des ordures, ils ont besoin de données de maintenance.

  • Je ne connais pas Python, mais je suis à peu près sûr qu'il a également besoin d'une référence à la classe et d'informations sur l'entretien ménager pour le garbage collector.

Michael Borgwardt
la source
Il y a actuellement du travail dans OpenJDK pour réduire la taille des en-têtes d'objets, petites mais importantes étapes :-)
Martijn Verburg
En C ++, seules les classes polymorphes ont besoin de vtables. std::pair<int, float>est une classe simple qui n'a pas du tout besoin d'une table virtuelle. Par conséquent, il peut très bien tenir sur 8 octets. De plus, les pointeurs intelligents n'ont pas réellement besoin d'ajouter des tâches ménagères. Un contre-exemple clair est std::unique_ptr<T>, qui est généralement aussi grand que le brut T*(unique_ptr bien sûr ne fait pas GC).
MSalters
4
C a également une surcharge, chaque mallocbloc de mémoire alloué a besoin d'un en-tête qui l' freeutilise ensuite.
herby
Au moins une bibliothèque malloc que je connais utilise un en-tête de 8 octets sur les systèmes 32 bits (qui est une longueur de 4 octets entre crochets par deux ensembles de valeurs sentinelles de 2 octets, IIRC).
Donal Fellows