Teknologian jakaminen

JVM:ään liittyvä

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

JDK-arkkitehtuuri

Java-kielen monialustaiset ominaisuudet

JVM:n yleinen rakenne ja muistimalli

JVM-muistin parametriasetukset

Spring Boot -ohjelman JVM-parametrien asetusmuoto (Tomcat-käynnistys lisätään suoraan catalina.sh-tiedostoon bin-hakemistossa):

java -Xms2048M -Xmx2048M -Xmn1024M -Xss512K -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M -jar microservice-eureka-server.jar

tiivistettynä:

Mitä pienempi -Xss-asetus on, sitä pienempi laskenta-arvo, mikä tarkoittaa, että säiepinoon voidaan varata vähemmän pinokehyksiä, mutta avattavien säikeiden määrä on suurempi koko JVM:lle.

-Xss: kunkin säikeen pinokoko, oletusarvo 1M

-Xms: Aseta keon alkuperäinen käytettävissä oleva koko, oletusarvo on 1/64 fyysisestä muistista

-Xmx: Aseta kasan suurin käytettävissä oleva koko, oletusarvo on 1/4 fyysisestä muistista

-Xmn: uuden sukupolven koko

-XX:NewRatio: Oletusarvo 2 tarkoittaa, että uuden sukupolven osuus on 1/2 vanhasta sukupolvesta ja 1/3 koko kasamuistista.

-XX:SurvivorRatio: Oletusarvo 8 tarkoittaa, että selviytymisalue vie 1/8 Eden-muistista, eli 1/10 uuden sukupolven muistista.

Metaavaruudessa on kaksi JVM-parametria: -XX:MetaspaceSize=N ja -XX:MaxMetaspaceSize=N

-XX: MaxMetaspaceSize: Aseta metatilan enimmäiskoko Oletusarvo on -1, mikä tarkoittaa, että rajoitusta ei ole, tai sitä rajoittaa vain paikallinen muisti.

-XX: MetaspaceSize: Määritä metaavaruuden alkukynnys, joka laukaisee Fullgc:n (metaspacelle ei ole kiinteää alkukokoa), oletusarvo on noin 21M Kun tämä arvo saavutetaan, täysi gc käynnistyy tyypin purkamista varten keräilijä säätää tätä arvoa: Jos vapautuu suuri määrä tilaa, vähennä arvoa asianmukaisesti, jos vapautuu vähän tilaa, lisää arvoa asianmukaisesti ylittämättä -XX:MaxMetaspaceSize (jos asetettu). Tällä on eri merkitys kuin -XX:PermSize-parametrilla aiemmissa jdk-versioissa -XX:PermSize edustaa pysyvän sukupolven alkukapasiteettia.

Koska metaavaruuden koon muuttaminen vaatii Full GC:tä, tämä on erittäin kallis toimenpide yleensä suositellaan JVM-parametreissa MetaspaceSize ja MaxMetaspaceSize samat arvot ja ne suuremmat kuin alkuperäinen arvo Koneessa, jossa on 8G fyysinen muisti, asetan yleensä molemmat arvot arvoon 256M.

Esineiden luominen

Objektin otsikko

HotSpot-virtuaalikoneessa muistiin tallennettujen objektien asettelu voidaan jakaa kolmeen alueeseen: objektin otsikko (Header), ilmentymätiedot (Instance Data) ja kohdistustäyte (Padding). HotSpot-virtuaalikoneen objektiotsikko sisältää kaksi osaa tietoa. Ensimmäistä osaa käytetään itse objektin ajonaikaisten tietojen tallentamiseen, kuten hash-koodi (HashCode), GC-sukupolven ikä, lukon tila lippu, säikeen pitämä lukko. , puolueellinen säikeen tunnus, suosikin aikaleimat jne. Objektin otsikon toinen osa on tyyppiosoitin, joka on objektin osoitin sen luokan metatietoihin. Virtuaalikone määrittää tämän osoittimen avulla, minkä luokan esiintymä objekti on.

32-bittinen objektiotsikko

64-bittinen objektiotsikko

osoittimen pakkaus

1. 32-bittisten osoittimien käyttäminen HotSpotissa 64-bittisessä alustassa käyttää noin 1,5 kertaa enemmän muistia Samaan aikaan GC on myös suuremman paineen alla

2. Vähentääksesi muistin kulutusta 64-bittisissä alustoissa, ota osoittimen pakkaustoiminto käyttöön

3. jvm:ssä 32-bittiset osoitteet tukevat jopa 4 Gt muistia (2 - 32. potenssi), joka voidaan optimoida pakkaamalla ja koodaamalla objektiosoitin, kun se tallennetaan kasomuistiin, ja dekoodaamalla se poiston jälkeen cpu-rekisteriin (olioosoitin on kasassa Se on 32 bittiä, 35 bittiä rekisterissä, 2 35. potenssiin = 32G), jolloin jvm voi tukea suurempia muistikokoonpanoja (pienempi tai yhtä suuri kuin 32 G) käyttämällä vain 32-bittiset osoitteet

4. Kun kasamuisti on pienempi kuin 4G, osoittimen pakkausta ei tarvitse ottaa käyttöön. Jvm poistaa suoraan korkean 32-bittisen osoitteen, eli käyttää matalaa virtuaalista osoiteavaruutta.

5. Kun pinomuisti on suurempi kuin 32G, pakkausosoitin muuttuu virheelliseksi ja 64-bittinen (eli 8 tavua) pakotetaan käsittelemään Java-objektia. Tämä aiheuttaa ongelman 1, joten on parempi olla käyttämättä keon muisti on suurempi kuin 32 Gt.

Escape-analyysi ja kohdepinon kohdistamisen otsikon korvaaminen

Tässä tapauksessa JVM voi optimoida objektin muistin varaussijainnin ottamalla käyttöön Escape-analyysiparametrin (-XX:+DoEscapeAnalysis), jotta se varataan ensin pinossa skalaarikorvauksen avulla (varaus pinossa on). oletuksena käytössä JDK7:n jälkeen Jos haluat Poista käytöstä parametrien avulla (-XX:-DoEscapeAnalysis)

Skalaarikorvaus: Kun estoanalyysin avulla päätetään, että objektiin ei päästä ulkopuolelta ja objektia voidaan edelleen hajottaa, JVM ei luo objektia, vaan hajottaa objektin jäsenmuuttujat useiksi tämän menetelmän käyttämiksi jäsenmuuttujiksi. korvaa ne Nämä korvaavat jäsenmuuttujat varaavat tilaa pinokehyksessä tai rekisterissä, jotta objektille ei ole riittävästi muistia, koska siinä ei ole suurta vierekkäistä tilaa. Ota käyttöön skalaarikorvausparametrit (-XX:+EliminateAllocations), joka on oletuksena käytössä JDK7:n jälkeen.

Skalaari ja aggregaattisuureet: Skalaari on suure, jota ei voida hajottaa enempää, ja JAVA:n perustietotyyppi on skalaari (kuten int, long ja muut perustietotyypit ja viitetyypit jne.) Skalaarin vastakohta on määrä, joka voidaan edelleen hajottaa, ja Tätä määrää kutsutaan polymerointimääräksi. JAVA:ssa objektit ovat aggregaatteja, jotka voidaan hajottaa edelleen.

Suuret esineet tulevat suoraan vanhaan sukupolveen

Suuret objektit ovat objekteja, jotka vaativat suuren määrän jatkuvaa muistitilaa (kuten merkkijonoja ja taulukoita). JVM-parametri -XX:PretenureSizeThreshold voi asettaa suurten kohteiden koon.

Aseta esimerkiksi JVM-parametrit: -XX:PretenureSizeThreshold=1000000 (yksikkö on tavua) -XX:+UseSerialGC Jos suoritat ensimmäisen yllä olevan ohjelman, huomaat, että suuri objekti siirtyy suoraan vanhaan sukupolveen.

Miksi pitää olla näin?

Kopiointitoimintojen välttämiseksi varattaessa muistia suurille kohteille ja tehokkuuden vähentämiseksi.

Objektin dynaaminen ikäarviointi

Survivor-alueella, johon kohde on tällä hetkellä sijoitettu (yksi alueista, s-alue, jolle esine on sijoitettu), esineerän kokonaiskoko on suurempi kuin 50 % tämän Survivor-alueen muistikoosta (-XX :TargetSurvivorRatio voidaan määrittää, niin se on tällä hetkellä suurempi kuin Objektit, jotka vastaavat tämän objektierän enimmäisikää, voivat syöttää suoraan vanhuuteen. Esimerkiksi Survivor-alueella on erä esineitä monien ikäisten kohteiden summa 1 + ikä 2 + ikä n ylittää 50% Survivor-alueesta Tämä Tällä hetkellä kaikki objektit, joiden ikä on n (mukaan lukien) ja sitä vanhemmat, siirretään vanhaan sukupolveen. Tämä sääntö itse asiassa toivoo, että esineet, jotka voivat säilyä pitkään, pääsevät vanhuuteen mahdollisimman pian. Objektin dynaaminen iän arviointimekanismi laukeaa yleensä pienen gc:n jälkeen.

Vanhan sukupolven tilanjakotakuumekanismi

Ennen jokaista nuoren sukupolven pientä gc:tä JVM laskee jäljellä olevan vapaan tilan vanhassa sukupolvessa.

Jos käytettävissä oleva tila on pienempi kuin nuoren sukupolven kaikkien olemassa olevien esineiden (mukaan lukien roskat) kokojen summa

Se tarkistaa, onko parametri "-XX:-HandlePromotionFailure" (asetettu oletuksena jdk1.8:ssa) asetettu.

Jos tämä parametri on olemassa, se tarkistaa, onko vanhan sukupolven käytettävissä olevan muistin koko suurempi kuin niiden objektien keskimääräinen koko, jotka tulivat vanhaan sukupolveen jokaisen edellisen pienen gc:n jälkeen.

Jos edellisen vaiheen tulos on pienempi tai edellä mainittuja parametreja ei ole asetettu, laukeaa Full gc, ja vanha ja nuori sukupolvi kerätään yhteen, jos tilaa ei vieläkään ole tarpeeksi kierrätyksen jälkeen tapahtuu "OOM".

Tietenkin, jos jäljellä olevien, vanhaan sukupolveen siirrettävien objektien koko on edelleen suurempi kuin vanhassa sukupolvessa käytettävissä oleva tila, myös täysi gc laukeaa, jos siellä on ei vieläkään ole tilaa eloonjääneille esineille pienen gc:n jälkeen, se myös "OOM" tapahtuu

Saavutettavuuden analysointialgoritmi

Analysoidaan JVM-luokan latausmekanismia JDK-lähdekooditasolta

Luokan latausprosessi

Luokkalataajat ja vanhempien delegointimekanismi

Miksi vanhempien delegaatio kannattaa suunnitella?

Yksityiskohtainen kuvaus Tomcat mukautetun kuormaajan

Useita pääluokan tomcat-kuormaajia:

commonLoader: Tomcatin yksinkertaisin luokkalataaja voidaan käyttää itse Tomcat-säilön ja jokaisen Web-sovelluksen kautta.

catalinaLoader: Tomcat-säilön yksityinen luokkalataaja Latauspolun luokat eivät näy Webappille.

shareLoader: Jokaisen Web-sovelluksen jakama luokkalataaja Latauspolun luokat näkyvät kaikille Web-sovelluksille, mutta eivät Tomcat-säilölle.

WebappClassLoader: Jokaisen Webappin yksityinen luokkalataaja näkyy vain nykyiselle Webappille, kuten sotapaketissa olevien luokkien lataaminen Erilaisia ​​jousiversioita esitellään, jotta toteutus voi ladata vastaavat jousiversiot.

muisti malli

Roskien keräysalgoritmi

roskankerääjä

Taustalla olevan jätteenkeräysalgoritmin toteutus