Uključivanje metode u JVM

1. Uvod

U ovom ćemo uputstvu pogledati što je umetanje metoda u Java virtualni stroj i kako to funkcionira.

Također ćemo vidjeti kako iz JVM-a dobiti i pročitati informacije povezane s ugradnjom i što možemo učiniti s tim podacima kako bismo optimizirali naš kôd.

2. Koja je metoda inlinziranja?

U osnovi, inlining je način za optimizaciju kompajliranog izvornog koda u vrijeme izvođenja zamjenom zaziva najčešće izvedenih metoda s njegovim tijelima.

Iako je riječ o kompilaciji, ona je ne izvodi tradicionalna javac prevoditelj, ali sam JVM. Da budem precizniji, to je odgovornost kompajlera Just-In-Time (JIT), koji je dio JVM-a; javac proizvodi samo bajt kod i omogućuje JIT-u da napravi magiju i optimizira izvorni kod.

Jedna od najvažnijih posljedica ovog pristupa je ta da ako kompajliramo kod koristeći staru Javu, isti.razred datoteka će biti brža na novijim JVM-ovima. Na ovaj način ne trebamo rekompajlirati izvorni kod, već samo ažurirati Javu.

3. Kako JIT to radi?

U osnovi, JIT kompajler pokušava ugraditi metode koje često nazivamo kako bismo mogli izbjeći općenite pozive metode. Dvoje stvari uzimaju u obzir prilikom odlučivanja hoće li se metoda ugraditi ili ne.

Prvo, koristi brojače kako bi pratio koliko puta pozivamo metodu. Kada se metoda pozove više od određenog broja puta, ona postaje "vruća". Ovaj je prag prema zadanim postavkama postavljen na 10.000, ali možemo ga konfigurirati putem zastavice JVM tijekom pokretanja Jave. Definitivno ne želimo sve ugrađivati, jer bi to zahtijevalo vrijeme i stvorilo bi golem bajt kod.

Morali bismo imati na umu da će se inliniranje odvijati tek kad dođemo u stabilno stanje. To znači da ćemo izvršenje morati ponoviti nekoliko puta kako bismo pružili dovoljno podataka o profiliranju za JIT prevodilac.

Nadalje, "vruće" ne garantira da će metoda biti navedena. Ako je prevelik, JIT ga neće ugraditi. Prihvatljiva veličina ograničena je -XX: FreqInlineSize = zastava koja određuje maksimalan broj uputa za bajt kod za umetanje u metodu.

Unatoč tome, toplo se preporučuje da ne mijenjate zadanu vrijednost ove zastave, osim ako nismo potpuno sigurni da znamo kakav bi utjecaj mogla imati. Zadana vrijednost ovisi o platformi - za 64-bitni Linux iznosi 325.

JIT se ugrađuje statički, privatni, ili konačni metode općenito. I dok javnost metode su također kandidati za uvrštavanje, neće svaka javna metoda nužno biti uvrštena. JVM mora utvrditi da postoji samo jedna primjena takve metode. Bilo koji dodatni podrazred spriječio bi umetanje i performanse će se neizbježno smanjiti.

4. Pronalaženje vrućih metoda

Sigurno ne želimo pogoditi što JIT radi. Stoga nam treba neki način da vidimo koje su metode ucrtane ili nisu. To možemo lako postići i prijaviti sve ove podatke na standardni izlaz postavljanjem nekih dodatnih JVM zastavica tijekom pokretanja:

-XX: + PrintCompilation -XX: + UnlockDiagnosticVMOptions -XX: + PrintInlining

Prva zastava zabilježit će se kad se dogodi JIT kompilacija. Druga zastava omogućuje dodatne zastave uključujući -XX: + PrintInlining, koji će ispisati koje se metode navode i gdje.

To će nam pokazati obrubljene metode u obliku stabla. Listovi su označeni i označeni jednom od sljedećih opcija:

  • u liniji (vruće) - ova metoda je označena kao vruća i ucrtana je
  • prevelik - metoda nije vruća, ali također je i njezin generirani bytecode prevelik, pa nije ugrađen
  • vruća metoda prevelika - ovo je vruća metoda, ali nije uvrštena jer je bytecode prevelik

Trebali bismo obratiti pažnju na treću vrijednost i pokušati optimizirati metode s oznakom "vruća metoda prevelika".

Općenito, ako nađemo vruću metodu s vrlo složenom uvjetnom izjavom, trebali bismo pokušati odvojiti sadržaj ako-i povećati granularnost tako da JIT može optimizirati kôd. Isto vrijedi i za sklopka i za-izjave petlje.

Možemo zaključiti da je umetanje ručne metode nešto što ne trebamo učiniti da bismo optimizirali naš kôd. JVM to čini učinkovitije i možda bismo kôd učinili dugim i teškim za praćenje.

4.1. Primjer

Pogledajmo sada kako to možemo provjeriti u praksi. Prvo ćemo stvoriti jednostavnu klasu koja izračunava zbroj prve N uzastopni pozitivni cijeli brojevi:

javna klasa ConsecutiveNumbersSum {private long totalSum; private int totalNumbers; javni ConsecutiveNumbersSum (int totalNumbers) {this.totalNumbers = totalNumbers; } javni long getTotalSum () {totalSum = 0; za (int i = 0; i <ukupni brojevi; i ++) {totalSum + = i; } return totalSum; }}

Dalje, jednostavna metoda iskoristit će klasu za izvođenje izračuna:

privatna statička duga izračunajSum (int n) {return new ConsecutiveNumbersSum (n) .getTotalSum (); }

Na kraju ćemo metodu pozvati nekoliko puta i vidjeti što će se dogoditi:

za (int i = 1; i <BROJEVI_FITACIJA; i ++) {izračunSum (i); }

U prvom ćemo ga pokrenuti 1000 puta (manje od gore spomenute vrijednosti od 10 000). Ako na izlazu pretražimo izračunaj zbroj () metodu, nećemo je naći. To se očekuje jer ga nismo nazvali dovoljno puta.

Ako sada promijenimo broj ponavljanja na 15 000 i ponovo pretražimo izlaz, vidjet ćemo:

664 262% com.baeldung.inlining.InliningExample :: main @ 2 (21 bajta) @ 10 com.baeldung.inlining.InliningExample :: izračunaj Zbroj (12 bajtova) inline (vruće)

Vidimo da ovaj put metoda ispunjava uvjete za ugradnju i da ju je JVM ocrtao.

Važno je ponovno spomenuti da ako je metoda prevelika, JIT je neće ugraditi, bez obzira na broj iteracija. To možemo provjeriti dodavanjem druge zastavice prilikom pokretanja aplikacije:

-XX: FreqInlineSize = 10

Kao što možemo vidjeti u prethodnom izlazu, veličina naše metode je 12 bajtova. The -XX:FreqInlineSize zastavica ograničit će veličinu metode koja ispunjava uvjete za ugradnju na 10 bajtova. Slijedom toga, umetanje se ovaj put ne bi trebalo odvijati. I doista, to možemo potvrditi još jednim pogledom na izlaz:

330 266% com.baeldung.inlining.InliningExample :: main @ 2 (21 bajta) @ 10 com.baeldung.inlining.InliningExample :: izračunajSum (12 bajtova) vruća metoda prevelika

Iako smo ovdje radi ilustracije promijenili vrijednost zastave, moramo naglasiti preporuku da se ne mijenja zadana vrijednost -XX: FreqInlineSize zastava ako nije prijeko potrebno.

5. Zaključak

U ovom smo članku vidjeli koja je ugradnja metoda u JVM i kako to čini JIT. Opisali smo kako možemo provjeriti ispunjavaju li naše metode mogućnost uvrštavanja ili ne i predložili kako iskoristiti ove podatke pokušavajući smanjiti veličinu često zvanih dugih metoda koje su prevelike da bi se uvrstile.

Na kraju smo ilustrirali kako u praksi možemo prepoznati vruću metodu.

Svi isječci koda spomenuti u članku mogu se naći u našem GitHub spremištu.


$config[zx-auto] not found$config[zx-overlay] not found