2017-08-10 2 views
3

Ne me prenez pas au mot. Je ne fais que répéter ce que j'ai rassemblé de différentes sources. HotSpot JVM utilise des tampons d'allocation de threads locaux (TLAB). Les TLAB peuvent être synchronisés ou non. La plupart du temps, les TLAB ne sont pas synchronisés et un thread peut donc être alloué très rapidement. Il existe un grand nombre de ces TLAB afin que les threads actifs obtiennent leurs propres TLAB. Les threads moins actifs partagent un TLAB synchronisé. Lorsqu'un thread épuise son TLAB, il obtient un autre TLAB d'un pool. Lorsque le pool est à court de TLAB, Young GC est déclenché ou nécessaire. Lorsque le pool ne contient plus de TLAB, il reste des TLAB avec de l'espace libre. Cet "espace inutilisé" s'additionne et est significatif. On peut voir cet espace car le GC est déclenché avant que la taille du tas réservée ou la taille maximale du tas ne soit atteinte. Ainsi, le tas est effectivement 10-30% plus petit. Au moins, c'est ce que je devine en regardant les graphiques d'utilisation du tas.Comment optimiser l'espace inutilisé dans le tas Java

Comment régler la JVM pour réduire l'espace inutilisé?

Répondre

2

Vous pouvez modifier ce paramètre avec l'option de ligne de commande -XX:TLABSize

Cependant, comme avec la plupart de ces paramètres « en profondeur et sale », vous devriez être très prudent lorsque vous modifiez les et de surveiller l'effet de vos modifications étroitement .

2

Vous avez raison, une fois qu'il n'y a pas de TLAB, il y aura une collection de jeunes générations et ils seront nettoyés.

Je ne peux pas dire grand-chose, mais il est ResizeTLAB qui permet de la machine virtuelle Java pour le redimensionner en fonction des allocations statistiques, je suppose, la taille eden, etc. Il y a aussi un indicateur appelé TLABWasteTargetPercent (par défaut, il est 1%). Lorsque le TLAB actuel ne peut pas contenir un objet de plus, la JVM doit décider quoi faire: affecter directement au tas ou allouer un nouveau TLAB.

Si cette taille d'objet est supérieure à 1% of the current TLAB size, elle est allouée directement; sinon, le TLAB actuel est retiré.

Alors disons que la taille actuelle du TLAB (TLABSize, par défaut, il est égal à zéro, ce qui signifie qu'il sera adaptatif) est 100 bytes (tous les chiffres sont théoriques), 1% de c'est 1 byte - c'est le TLABWasteTargetPercent. Actuellement, votre TLAB est rempli avec 98 octets et votre objet que vous souhaitez allouer est de 3 octets. Il ne rentre pas dans ce TLAB et en même temps il est plus grand que le seuil de 1 octet => il est directement affecté sur le tas. L'inverse est que votre TLAB est plein avec 99,7 octets et vous essayez d'allouer un objet de 1/2 octet - il ne rentre pas; mais il est plus petit que 1 octet; ainsi ce TLAB est engagé et un nouveau vous est donné. Si je comprends bien, il y a un autre paramètre appelé TLABWasteIncrement - quand vous ne parvenez pas à allouer dans le TLAB (et allouez directement dans le tas) - de sorte que cette histoire ne se produise pas pour toujours, le TLABWasteTargetPercent est augmenté de cette valeur (défaut de 4%) augmentant les chances de retirer ce TLAB.

Il y a aussi TLABAllocationWeight et TLABRefillWasteFraction - probablement mettre à jour ce poste un peu plus tard avec eux