Java >> Java tutorial >  >> JVM

Udforsker JVM Tuning Flags

1. Oversigt

Det er muligt at tune HotSpot JVM med en række forskellige tuning flag. Da der er hundredvis af sådanne flag, kan det være lidt skræmmende at holde styr på dem og deres standardværdier.

I dette selvstudie vil vi introducere et par måder at opdage sådanne tuning-flag og lære at arbejde med dem.

2. Oversigt over Java-indstillinger

 java  kommandoen understøtter en lang række flag, der falder ind under følgende kategorier:

  • Standardindstillinger, der med garanti understøttes af alle JVM-implementeringer derude. Normalt bruges disse muligheder til daglige handlinger såsom –classpath, -cp, –version,  og så videre
  • Ekstra muligheder, der ikke understøttes af alle JVM-implementeringer, og som normalt kan ændres. Disse muligheder starter med -X

Bemærk venligst, at vi ikke bør bruge disse ekstra muligheder tilfældigt. Desuden nogle af disse yderligere muligheder er mere avancerede og begynder med  -XX .

Igennem denne artikel vil vi fokusere på mere avancerede -XX  flag.

3. JVM Tuning Flag

For at angive de globale JVM-tuningflag kan vi aktivere PrintFlagsFinal  flag som følger:

>> java -XX:+PrintFlagsFinal -version
[Global flags]
    uintx CodeCacheExpansionSize                   = 65536                                  {pd product} {default}
     bool CompactStrings                           = true                                   {pd product} {default}
     bool DoEscapeAnalysis                         = true                                   {C2 product} {default}
   double G1ConcMarkStepDurationMillis             = 10.000000                                 {product} {default}
   size_t G1HeapRegionSize                         = 1048576                                   {product} {ergonomic}
    uintx MaxHeapFreeRatio                         = 70                                     {manageable} {default}

// truncated
openjdk version "14" 2020-03-17
OpenJDK Runtime Environment (build 14+36-1461)
OpenJDK 64-Bit Server VM (build 14+36-1461, mixed mode, sharing)

Som vist ovenfor har nogle flag standardværdier for denne særlige JVM-version.

Standardværdier for nogle flag kan være forskellige på forskellige platforme, hvilket er vist i den sidste kolonne. For eksempel produktet betyder, at standardindstillingen af ​​flaget er ensartet på tværs af alle platforme; pd-produktet betyder, at standardindstillingen af ​​flaget er platformsafhængig. Den overskuelige  værdier kan ændres dynamisk under kørsel.

3.1. Diagnostiske flag

 PrintFlagsFinal  flag viser dog ikke alle mulige tuning flag. For eksempel, for også at se diagnostiske tuning-flag, bør vi tilføje UnlockDiagnosticVMOptions  flag:

>> java -XX:+PrintFlagsFinal -version | wc -l
557

>> java -XX:+PrintFlagsFinal -XX:+UnlockDiagnosticVMOptions -version | wc -l
728

Det er klart, at der er et par hundrede flere flag, når vi inkluderer diagnostiske muligheder. For eksempel er udskrivning af native memory tracking-statistikker kun tilgængelig som en del af diagnostiske flag:

bool PrintNMTStatistics                       = false                                  {diagnostic} {default}

3.2. Eksperimentelle flag

For også at se eksperimentelle muligheder bør vi tilføje UnlockExperimentalVMOptions  flag:

>> java -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+PrintFlagsFinal -version | wc -l
809

3.3. JVMCI-flag

Fra og med Java 9 gør JVM compiler interface eller JVMCI os i stand til at bruge en compiler skrevet i Java, såsom Graal, som en dynamisk compiler.

For at se muligheder relateret til JVMCI, bør vi tilføje et par flere flag og også endda aktivere JVMCI:

>> java -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions \
>> -XX:+JVMCIPrintProperties -XX:+EnableJVMCI -XX:+PrintFlagsFinal  -version | wc -l
1516

Det meste af tiden skulle det dog være tilstrækkeligt at bruge globale, diagnostiske og eksperimentelle muligheder og hjælpe os med at finde det flag, vi har i tankerne.

3.4. At sætte det hele sammen

Disse kombinationer af muligheder kan hjælpe os med at finde et tuning flag, især når vi ikke husker det nøjagtige navn. For eksempel for at finde tuning-flaget relateret til bløde referencer i Java:

>> alias jflags="java -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+PrintFlagsFinal  -version"
>> jflags | grep Soft
size_t SoftMaxHeapSize                          = 4294967296                             {manageable} {ergonomic}
intx SoftRefLRUPolicyMSPerMB                    = 1000                                   {product} {default}

Ud fra resultatet kan vi nemt gætte, at SoftRefLRUPolicyMSPerMB er det flag, vi leder efter.

4. Forskellige typer flag

I det foregående afsnit overså vi et vigtigt emne:flagtyperne. Lad os tage et nyt kig på java -XX:+PrintFlagsFinal -version  output:

[Global flags]
    uintx CodeCacheExpansionSize                   = 65536                                  {pd product} {default}
     bool CompactStrings                           = true                                   {pd product} {default}
     bool DoEscapeAnalysis                         = true                                   {C2 product} {default}
   double G1ConcMarkStepDurationMillis             = 10.000000                                 {product} {default}
   size_t G1HeapRegionSize                         = 1048576                                   {product} {ergonomic}
    uintx MaxHeapFreeRatio                         = 70                                     {manageable} {default}
// truncated

Som vist ovenfor har hvert flag en bestemt type.

Booleske indstillinger bruges til enten at aktivere eller deaktivere en funktion . Sådanne muligheder kræver ikke en værdi. For at aktivere dem skal vi blot sætte et plustegn før valgmulighedens navn:

-XX:+PrintFlagsFinal

Tværtimod, for at deaktivere dem, skal vi tilføje et minustegn før deres navn:

-XX:-RestrictContended

Andre flagtyper skal have en argumentværdi. Det er muligt at adskille værdien fra valgmulighedens navn med et mellemrum, et kolon, et lighedstegn, eller argumentet kan følge direkte efter indstillingsnavnet (den nøjagtige syntaks er forskellig for hver mulighed):

-XX:ObjectAlignmentInBytes=16 -Xms5g -Xlog:gc

5. Dokumentation og kildekode

At finde det rigtige flagnavn er én ting. At finde ud af, hvad det pågældende flag laver under motorhjelmen, er en anden historie.

En måde at finde ud af denne slags detaljer er ved at se på dokumentationen. For eksempel dokumentationen til java  kommandoen i JDK-værktøjsspecifikationsafsnittet er et godt sted at starte.

Nogle gange kan ingen mængde dokumentation slå kildekoden. Derfor, hvis vi har navnet på et bestemt flag, så kan vi udforske JVM-kildekoden for at finde ud af, hvad der foregår.

For eksempel kan vi tjekke HotSpot JVM's kildekode fra GitHub eller endda deres Mercurial repository og derefter:

>> git clone [email protected]:openjdk/jdk14u.git openjdk
>> cd openjdk/src/hotspot
>> grep -FR 'PrintFlagsFinal' .
./share/runtime/globals.hpp:  product(bool, PrintFlagsFinal, false,                                   
./share/runtime/init.cpp:  if (PrintFlagsFinal || PrintFlagsRanges) {

Her leder vi efter alle filer, der indeholder PrintFlagsFinal  snor. Efter at have fundet de ansvarlige filer, kan vi se os omkring og se, hvordan det specifikke flag fungerer.

6. Konklusion

I denne artikel så vi, hvordan vi kunne finde næsten alle tilgængelige JVM-tuningflag og lærte også et par tricks til at arbejde med dem mere effektivt.


Java tag