Inleiding tot JVM Code Cache

1. Inleiding

In deze tutorial gaan we snel kijken naar en leren over het codecachegeheugen van de JVM.

2. Wat is de codecache?

Simpel gezegd, JVM Code Cache is een gebied waar JVM de bytecode opslaat die is gecompileerd in native code. We noemen elk blok van de uitvoerbare native code een nmethode. De nmethode kan een complete of inline Java-methode zijn.

De just-in-time (JIT) -compiler is de grootste gebruiker van het codecache-gebied. Daarom noemen sommige ontwikkelaars dit geheugen een JIT-codecache.

3. Afstemming van codecache

De codecache heeft een vaste grootte. Als het eenmaal vol is, zal de JVM geen aanvullende code meer compileren omdat de JIT-compiler nu is uitgeschakeld. Verder ontvangen we de "CodeCache is vol ... De compiler is uitgeschakeld" waarschuwingsbericht. Als gevolg hiervan zullen de prestaties van onze applicatie afnemen. Om dit te voorkomen, kunnen we de codecache afstemmen met de volgende grootte-opties:

  • InitialCodeCacheSize - de initiële grootte van de code-cache, standaard 160K
  • ReservedCodeCacheSize - de standaard maximale grootte is 48 MB
  • CodeCacheExpansionSize - de uitbreidingsgrootte van de codecache, 32 KB of 64 KB

Verhogen van de ReservedCodeCacheSize kan een oplossing zijn, maar dit is doorgaans slechts een tijdelijke oplossing.

Gelukkig biedt de JVM een UseCodeCacheFlushing optie om het leegmaken van het codecache-gebied te regelen. De standaardwaarde is false. Als we het inschakelen, is het maakt het bezette gebied vrij als aan de volgende voorwaarden is voldaan:

  • de codecache is vol; dit gebied wordt gespoeld als het een bepaalde drempel overschrijdt
  • het bepaalde interval is verstreken sinds de laatste schoonmaakbeurt
  • de voorgecompileerde code is niet hot genoeg. Voor elke gecompileerde methode houdt de JVM een speciale hotness-teller bij. Als de waarde van deze teller kleiner is dan een berekende drempel, maakt de JVM dit stuk voorgecompileerde code vrij

4. Gebruik van codecache

Om het gebruik van de codecache te volgen, moeten we de grootte van het momenteel gebruikte geheugen volgen.

Om informatie te krijgen over het gebruik van code cache, kunnen we de –XX: + PrintCodeCache JVM-optie. Nadat we onze applicatie hebben uitgevoerd, zien we een vergelijkbare uitvoer:

CodeCache: size = 32768Kb gebruikt = 542Kb max_used = 542Kb gratis = 32226Kb 

Laten we eens kijken wat elk van deze waarden betekent:

  • grootte in de uitvoer toont de maximale grootte van het geheugen, die identiek is aan ReservedCodeCacheSize
  • gebruikt is de werkelijke grootte van het geheugen dat momenteel in gebruik is
  • max_used is de maximale grootte die in gebruik is geweest
  • vrij is het resterende geheugen dat nog niet bezet is

De PrintCodeCache optie is erg handig, omdat we kunnen:

  • kijk wanneer het doorspoelen gebeurt
  • bepalen of we een kritiek punt van geheugengebruik hebben bereikt

5. Gesegmenteerde codecache

Vanaf Java 9 verdeelt de JVM de codecache in drie verschillende segmenten die elk een bepaald type gecompileerde code bevatten. Om specifieker te zijn, zijn er drie segmenten:

  • Het niet-methodesegment bevat interne JVM-gerelateerde code, zoals de bytecode-interpreter. Dit segment is standaard ongeveer 5 MB. Het is ook mogelijk om de segmentgrootte te configureren via de -XX: NonNMethodCodeHeapSize tuning vlag
  • Het geprofileerde codesegment bevat licht geoptimaliseerde code met een mogelijk korte levensduur. Hoewel de segmentgrootte standaard ongeveer 122 MB is, kunnen we deze wijzigen via de -XX: ProfiledCodeHeapSize tuning vlag
  • Het niet-geprofileerde segment bevat volledig geoptimaliseerde code met een potentieel lange levensduur. Evenzo is het standaard ongeveer 122 MB. Deze waarde is natuurlijk configureerbaar via de -XX: NonProfiledCodeHeapSize tuning vlag

Deze nieuwe structuur behandelt verschillende typen code die wordt nageleefd, wat leidt tot betere algehele prestaties.

Het scheiden van kortstondige gecompileerde code van langlevende code verbetert bijvoorbeeld de prestaties van de methode-sweeper, vooral omdat het een kleiner geheugengebied moet scannen.

6. Conclusie

Dit korte artikel bevat een korte inleiding tot de JVM Code Cache.

Daarnaast hebben we enkele gebruiks- en afstemmingsopties gepresenteerd om dit geheugengebied te bewaken en te diagnosticeren.