web-dev-qa-db-fra.com

Astuce derrière la JVM compressée Oops

Donc, je comprends que les oops compressés sont activés par défaut dans HotSpot VM maintenant. Il prend en charge cette fonctionnalité à partir de Java SE 6u23 via l’option VM _ -XX:+UseCompressedOops. Je comprends que cela permet une utilisation efficace du cache du processeur, car ces derniers peuvent contenir un plus grand nombre de références que s’ils devaient traiter des références de taille 64 bits. Mais ce que je ne comprends pas, c’est que l’utilisation de JVM 32 bits peut traiter jusqu’à 264 adresses.

Pour simplifier le problème, comment pouvons-nous traiter jusqu'à 24 l'adresse mémoire utilise seulement 2 bits? Qu'est-ce qui peut être un codage/décodage possible d'un tel schéma d'adresses?

15
Geek

Pour une explication détaillée de la fonction Oops compressée, voir le "Oops compressés dans la machine virtuelle Hotspot" article de John Rose @ Oracle.

La version TL; DR est:

  • sur les architectures informatiques modernes, les adresses mémoire sont des adresses sur octets,
  • Les références d'objet Java sont des adresses qui pointent au début d'un mot.1,
  • sur un ordinateur 64 bits, l'alignement des mots signifie que les 3 derniers bits d'une référence/adresse d'objet sont nuls2
  • ainsi, en décalant une adresse de 3 bits vers la droite, nous pouvons "compresser" jusqu'à 35 bits d'une adresse de 64 bits en un mot de 32 bits,
  • et, la décompression peut être effectuée en décalant de 3 bits vers la gauche, ce qui remet ces 3 bits nuls,
  • L'adressage sur 35 bits nous permet de représenter des pointeurs d'objet pour une mémoire mémoire pouvant atteindre 32 Go à l'aide de fichiers Oops compressés pouvant contenir des mots de 32 bits (demi-mots) sur une machine 64 bits.

Notez que ce only fonctionne sur une machine virtuelle Java 64 bits. Nous devons toujours être en mesure d’adresser la mémoire contenant ce tas (jusqu’à 32 Go)1, c’est-à-dire des adresses matérielles 64 bits (sur les architectures CPU/ordinateurs modernes).

Notez également qu'il y a une petite pénalité pour cela. c'est-à-dire les instructions de décalage requises pour la traduction entre références régulières et compressées. Cependant, le revers de la médaille est que moins de mémoire est utilisée3et les caches de mémoire sont généralement plus efficaces en conséquence. 

1 - En effet, les architectures informatiques modernes sont optimisées pour un accès mémoire aligné sur Word.

2 - Cela suppose que vous n'avez pas utilisé -XX:ObjectAlignmentInBytes pour augmenter l'alignement à partir de sa valeur par défaut (et minimale) de 8 octets.

3 - En fait, l’économie de mémoire dépend de l’application. Cela dépend de la perte moyenne d'alignement d'objet, des rapports de référence sur les champs non référencés, etc. Cela devient plus compliqué si vous envisagez de régler l'alignement de l'objet.


Pour simplifier le problème, comment pouvons-nous traiter jusqu'à 24 adresses de mémoire utilisant seulement 2 bits? Qu'est-ce qui peut être un codage/décodage possible d'un tel schéma d'adresses?

Vous ne pouvez pas aborder 24 adresses d'octet. Mais vous pouvez adresse 22 Adresses de mot (en supposant des mots de 32 bits) utilisant des adresses de mot de 2 bits. Si vous pouvez supposer que toutes les adresses d'octet sont alignées sur Word, vous pouvez alors compresser une adresse d'octet de 4 bits en une adresse de mot de 2 bits en la décalant par positions de 2 bits.

25
Stephen C

Ce n'est pas destiné aux JVM 32 bits. Cela permet d'alléger les frais supplémentaires occasionnés par les machines virtuelles Java 64 bits. Je pense que la page d'Oracle l'explique bien:

Compressé Oops 

Les oops compressés représentent des pointeurs Gérés (souvent, mais pas toujours, dans le logiciel JVM) en tant que décalages d'objet 32 bits par rapport à l'adresse de base de segment de mémoire Java 64 bits. Puisqu'ils sont Des décalages d'objet plutôt que des octets, ils peuvent être utilisés pour traiter jusqu'à jusqu'à quatre milliards d'objets (pas d'octets), ou une taille de tas d'environ . 32 gigaoctets. Pour les utiliser, ils doivent être mis à l'échelle par un facteur de 8 et Ajoutés à l'adresse de base du segment de mémoire Java pour trouver l'objet auquel ils Font référence. 

la source

9
Enno Shioji

https://blog.codecentric.de/en/2014/02/35gb-heap-less-32gb-Java-jvm-memory-oddities/

Je pense que cet article explique bien cela. Emporté:

Comme la structure de la mémoire de la machine virtuelle Java utilise un schéma d’adressage de 8 octets, ce qui signifie que les objets peuvent être à l’adresse 0, 8, 16, 24… mais pas à 2, 7 ou tout autre non multiple de 8, les oops compressés s’adressent aux positions virtuelles 0, 1, 2, 3 au lieu des valeurs réelles 0, 8, 16, 24. Pour passer de l’adresse compressée à l’adresse réelle, la machine virtuelle Java a juste besoin de la déplacer à gauche 3 fois. Facile.

4G * 8 = 32

0
Jiacai Liu

CompressedOops .

Extrait de l'article: Tous les pointeurs ne sont pas compressés. Les valeurs compressées sont des valeurs de 32 bits qui doivent être mises à l'échelle par un facteur 8 et ajoutées à une adresse de base de 64 bits pour trouver l'objet auquel elles font référence. à.

Notez maintenant que vous ne pouvez pas adresser 2 ^ 64 bits de mémoire avec ces pointeurs 32 bits, mais que vous pouvez accéder à beaucoup de Objects avec eux. Si vous avez un objet à l'emplacement de mémoire x, vous ne pouvez en avoir un autre à x+1. C'est pourquoi vous n'avez pas besoin d'accéder à tous les emplacements de mémoire. 

0
Kayaman