Différence entre "sur le tas" et "off-heap"
6 réponses
le magasin on-heap se réfère à des objets qui seront présents dans le tas Java (et également soumis à GC). D'un autre côté, la mémoire off-heap fait référence à des objets (sérialisés) gérés par EHCache, mais stockés à l'extérieur de la mémoire heap (et non soumis au GC). Alors que le stock off-heap continue d'être géré en mémoire, il est légèrement plus lent que le stock on-heap, mais toujours plus rapide que le disque.
Les détails internes impliqués dans la gestion et l'utilisation de la magasin hors-tas ne sont pas très évidents dans le lien affiché dans la question, il serait donc sage de vérifier les détails de Terracotta BigMemory , qui est utilisé pour gérer le magasin hors-disque. BigMemory (the off-heap store) doit être utilisé pour éviter les frais généraux de GC sur un tas qui est de plusieurs mégaoctets ou gigaoctets de grande taille. BigMemory utilise l'espace d'adresse mémoire du processus JVM, via bytebuffers directs qui ne sont pas soumis au GC contrairement à d'autres natifs Des objets Java.
de http://code.google.com/p/fast-serialization/wiki/QuickStartHeapOff
Qu'est-ce que le déchargement en tas ?
habituellement, tous les objets non-temporaires que vous allouez sont gérés par le collecteur de déchets de java. Bien que la VM fasse un travail décent en ramassant les ordures, à un certain point la VM doit faire un soi-disant "GC complet". Un GC complet consiste à numériser le tas complet attribué, ce qui signifie que le GC les pauses / ralentissements sont proportionnels à la taille d'un tas d'applications. Alors ne faites confiance à personne qui vous dit que "la mémoire est bon marché". Dans la mémoire java, la consommation nuit à la performance. En outre, vous pouvez obtenir des pauses notables en utilisant des tailles de tas > 1 Go. Cela peut être désagréable si vous avez des choses en temps quasi réel en cours, dans un cluster ou une grille, un processus java peut ne pas réagir et être abandonné du cluster.
cependant les applications de serveur d'aujourd'hui (souvent construit sur le dessus des cadres gonflés ;- )) exigent facilement des tas bien au-delà de 4 Go.
une solution à ces exigences de mémoire, est de "décharger" des parties des objets vers le tas Non-java (directement alloué à partir du système D'exploitation). Heureusement java.nio fournit des classes pour affecter/lire et écrire directement des morceaux de mémoire "non gérées" (même des fichiers cartographiés en mémoire).
donc on peut allouer de grandes quantités de mémoire "non gérée" et utiliser ceci pour sauver des objets là. Pour enregistrer des objets dans mémoire non managé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 offheap, plus tard l'objet peut être lu en utilisant la deserialisation.
la taille de tas gérée par la VM java peut être maintenue petite, donc les pauses GC sont dans le millis, tout le monde est heureux, le travail est fait.
il est clair, que la performance d'un tel tampon off heap dépend principalement de la performance de la sérialisation application. 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 les gigaoctets des sessions utilisateur (inactives). Une fois que l'utilisateur se connecte à votre application, vous pouvez accéder rapidement aux données liées à l'utilisateur sans avoir à traiter avec une base de données.
- mise en Cache des résultats de calculs (requêtes, les pages html ..) (applicable seulement si le calcul est plus lent que la désérialisation de l'objet résultat ofc).
- très simple et très rapide de la persistance à l'aide de fichiers mappés en mémoire
Edit: pour certains scénarios, on pourrait choisir des algorithmes de collecte des ordures plus sophistiqués tels que M Arkandsweep ou G1 pour supporter des tas plus grands (mais cela a aussi ses limites au-delà des tas de 16 Go). Il existe également une coentreprise commerciale avec une version améliorée de GC "sans pause" (Azul).
le tas est l'endroit dans la mémoire où vos objets alloués dynamiquement vivent. Si vous avez utilisé new
alors c'est sur le tas. C'est par opposition à l'espace de pile, qui est l'endroit où la fonction stack vie. Si vous avez une variable locale alors cette référence est sur la pile.
Le tas de Java est sujet à la collecte des ordures et les objets sont directement utilisables.
Ehcache's off-heap storage prend votre objet régulier hors du tas, le sérialise, et le stocke en octets dans un morceau de mémoire géré par EHCache. C'est comme le stocker sur disque, mais C'est toujours en RAM. Les objets ne sont pas directement utilisables dans cet état, ils doivent être désérialisé premier. Également pas soumis à la collecte des ordures.
le JVM ne sait rien à propos de la mémoire hors tas. Ehcache implémente un cache sur disque ainsi qu'un cache en mémoire.
Pas à 100%; cependant, il semble que le tas est un objet ou d'un ensemble de l'espace alloué (RAM) qui est construit dans la fonctionnalité du code Java lui-même ou, plus probablement, la fonctionnalité de ehcache lui-même, et l'arrêt de segment de mémoire Ram est-il propre système; cependant, il semble que c'est l'une ampleur plus lent qu'il n'est pas organisé, sens il ne peut pas utiliser un segment de mémoire (ce qui signifie un long espace de ram), et utilise à la place les différents espaces d'adressage sans doute un peu moins efficace.
puis, bien sûr, le niveau inférieur suivant est l'espace disque dur lui-même.
Je n'utilise pas ehcache, donc vous ne voudrez peut-être pas me faire confiance, mais c'est ce que j'ai trouvé dans leur documentation.