177 votes

Différence entre "on-heap" et "off-heap".

Ehcache parle de Mémoire on-heap et off-heap. Quelle est la différence ? Quels args de la JVM sont utilisés pour les configurer ?

0 votes

Pour savoir comment utiliser la mémoire hors-heap, voir : stackoverflow.com/a/30027374/895245

0 votes

Le lien dans la question ne fonctionne pas. Nouveau lien vers la dernière version : ehcache.org/documentation/3.8/tiering.html#off-heap

198voto

Vineet Reynolds Points 40529

Le magasin on-heap fait référence aux objets qui seront présents dans le tas Java (et également soumis à la GC). D'autre part, le magasin off-heap fait référence aux objets (sérialisés) qui sont gérés par EHCache, mais stockés en dehors du tas (et également non soumis à la GC). Comme le magasin hors tas continue à être géré en mémoire, il est légèrement plus lent que le magasin sur tas, mais toujours plus rapide que le magasin sur disque.

Les détails internes impliqués dans la gestion et l'utilisation du magasin hors du tas ne sont pas très évidents dans le lien posté dans la question, donc il serait sage de vérifier les détails de Terracotta BigMemory qui est utilisé pour gérer le magasin hors disque. BigMemory (le magasin hors tas) doit être utilisé pour éviter la surcharge de la GC sur un tas de plusieurs mégaoctets ou gigaoctets. BigMemory utilise l'espace d'adressage mémoire du processus JVM, par le biais de direct ByteBuffers qui ne sont pas soumis à la GC contrairement aux autres objets Java natifs.

4 votes

Les ByteBuffers directs offrent un accès à la mémoire non gérée, mais sont eux-mêmes soumis à la GC (contrairement aux données qu'ils pointent). Ceci est important car un ByteBuffer direct (le type ByteBuffer.allocateDirect, pas le type MMap) sera collecté par la GC et lorsqu'il sera collecté, son Deallocater sera déclenché, collectant ainsi la mémoire non gérée.

0 votes

L'utilisation de Unsafe pour allouer des objets semble avoir des performances de lecture et d'écriture nettement supérieures à celles de Onheap/DirectByteBuffers/ByteBuffers. ashkrit.blogspot.com/2013/07/

117voto

R.Moeller Points 985

De http://code.google.com/p/fast-serialization/wiki/QuickStartHeapOff

Qu'est-ce que le déchargement en tas ?

En général, tous les objets non temporaires que vous allouez sont gérés par le ramasseur de déchets de Java. Bien que la VM fasse un travail décent en matière de collecte des déchets, à un certain moment, la VM doit effectuer une GC complète. Une GC complète implique l'analyse de la totalité du tas alloué, ce qui signifie que les pauses/ralentissements de la GC sont proportionnels à la taille du tas d'une application. Ne faites donc pas confiance à ceux qui vous disent que la mémoire est bon marché. En Java, la consommation de mémoire nuit aux performances. De plus, vous pouvez obtenir des pauses notables lorsque la taille du tas est supérieure à 1 Go. Cela peut être désagréable si vous avez des activités en temps quasi réel, dans un cluster ou une grille, un processus java peut ne plus répondre et être abandonné du cluster.

Cependant, les applications serveur actuelles (souvent construites sur des frameworks gonflants ;-) ) nécessitent facilement des tas bien au-delà de 4 Go.

Une solution à ces besoins en mémoire consiste à "décharger" certaines parties des objets vers le tas non Java (directement alloué par le système d'exploitation). Heureusement, java.nio fournit des classes permettant d'allouer/lire et écrire directement des morceaux de mémoire "non gérés" (même des fichiers mappés en mémoire).

On peut donc allouer de grandes quantités de mémoire "non gérée" et l'utiliser pour y sauvegarder des objets. Afin de sauvegarder des objets arbitraires dans la mémoire non gérée, la solution la plus viable est l'utilisation de la sérialisation. Cela signifie que l'application sérialise les objets dans la mémoire hors-hachette, et que plus tard, l'objet peut être lu en utilisant la désérialisation.

La taille du tas gérée par la VM java peut être maintenue à un faible niveau, de sorte que les pauses GC sont de l'ordre du millième, tout le monde est content, le travail est fait.

Il est clair que la performance d'un tel tampon hors tas dépend principalement de la performance de l'implémentation de la sérialisation. Bonne nouvelle : pour une raison quelconque, la sérialisation FST est assez rapide :-).

Exemples de scénarios d'utilisation :

  • Cache de session dans une application serveur. Utilisez un fichier mappé en mémoire pour stocker des gigaoctets de sessions utilisateur (inactives). Une fois que l'utilisateur s'est connecté à votre application, vous pouvez accéder rapidement aux données relatives à l'utilisateur sans avoir à vous occuper d'une base de données.
  • Mise en cache des résultats de calcul (requêtes, pages html, ..) (seulement applicable si le calcul est plus lent que la désérialisation de l'objet résultat ofc).
  • persistance très simple et rapide à l'aide de fichiers mappés en mémoire

Edit : Pour certains scénarios, on peut choisir des algorithmes de Garbage Collection plus sophistiqués comme ConcurrentMarkAndSweep ou G1 pour supporter des tas plus grands (mais cela a aussi ses limites au-delà de 16GB). Il existe également une JVM commerciale avec une GC améliorée sans pause (Azul).

4 votes

"allouer de grandes quantités de mémoire 'non gérée' et l'utiliser pour y sauvegarder des objets" - vous ne pouvez pas sauvegarder des objets hors du tas. Vous pouvez stocker des primitives, vous pouvez les envelopper dans la bibliothèque que vous voulez, mais ce ne sont pas des objets. Les données que vous placez hors du tas n'ont pas d'en-tête d'objet, vous ne pouvez pas les synchroniser, vous ne pouvez pas vous y référer avec un champ de référence dans un autre objet.

46voto

Adam Points 7110

Le tas est l'endroit de la mémoire où vivent vos objets alloués dynamiquement. Si vous avez utilisé new alors c'est sur le tas. Par opposition à l'espace de la pile, qui est l'endroit où se trouve la pile des fonctions. Si vous avez une variable locale, cette référence se trouve sur la pile. Le tas de Java est soumis au ramassage des ordures et les objets sont utilisables directement.

Le stockage hors du tas d'EHCache prend votre objet régulier du tas, le sérialise et le stocke sous forme d'octets dans un morceau de mémoire géré par EHCache. C'est comme s'il était stocké sur le disque mais toujours en RAM. Les objets ne sont pas directement utilisables dans cet état, ils doivent d'abord être désérialisés. Ils ne sont pas non plus soumis au ramassage des ordures.

0 votes

N'est-il pas simplement toujours dans le tas mais sous une forme sérialisée ?

1 votes

En quoi cela le rend-il plus efficace ?

3 votes

Il existe de nombreux moyens. Puisque les objets ne se trouvent plus sur le tas principal de Java, ils ne font pas perdre de temps au ramasseur de déchets, ils ne fragmentent pas le tas de la JVM et ils libèrent de l'espace pour d'autres objets plus utilisés. De plus, étant donné qu'ils sont sérialisés et qu'ils ne seront probablement pas nécessaires dans un avenir immédiat, ils peuvent être compressés, déplacés selon les besoins, ou même mis en page sur le disque.

2voto

msj121 Points 913

Pas à 100% ; cependant, il semble que le tas soit un objet ou un ensemble d'espace alloué (sur la RAM) qui est intégré dans la fonctionnalité du code, soit Java lui-même, soit plus probablement la fonctionnalité de ehcache lui-même, et la RAM hors tas est également un système propre ; cependant, il semble que ce soit une magnitude plus lente car elle n'est pas aussi organisée, ce qui signifie qu'elle ne peut pas utiliser un tas (c'est-à-dire un long ensemble d'espace de RAM), et utilise à la place différents espaces d'adresses, ce qui la rend probablement légèrement moins efficace.

Ensuite, bien sûr, le niveau inférieur suivant est l'espace du disque dur lui-même.

Je n'utilise pas ehcache, donc vous ne devez pas me croire, mais c'est ce que j'ai compris de leur documentation.

1voto

gatkin Points 1193

La JVM ne sait rien de la mémoire hors-heap. Ehcache implémente un cache sur disque ainsi qu'un cache en mémoire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X