4. Miksi pysyvä sukupolvi (PermGen) pitäisi korvata metaavaruudella (MetaSpace)?
5. Ymmärrätkö kasatilan perusrakenteen? Missä olosuhteissa esine tulee vanhaan sukupolveen?
6. Mille muistialueelle on sijoitettu suuria esineitä?
7. Mikä on Java-objektien luontiprosessi?
Kysymys Vastaus
1. Mistä osista JVM koostuu?
Vastaus: JVM on suoritettava tiedostotavukoodi (.class) tiedostojen virtuaalitietokone, joka tarjoaa myös muistinhallinnan, roskienkeruun ja muita mekanismeja. Se sisältää seuraavat pääosat.
Luokan latausalijärjestelmä: Vastaa tavukooditiedostojen (.class) lataamisesta JVM:ään.
Ajonaikainen tietoalue: on JVM:n suorittamisen aikana käyttämä muistialue.
Suoritusmoottori: Vastaa tavukoodin tulkinnasta tai kääntämisestä konekoodiksi prosessorin suorittamista varten.
Natiivikirjaston käyttöliittymä: Tarjoaa joukon sovellusliittymiä käyttöjärjestelmällä tai muilla kielillä kirjoitettujen alkuperäiskirjastojen kutsumiseen.
2. Mitä alueita suoritusaikatietoalue sisältää?
Vastaus: Ajonaikainen data-alue on muistialue, jonka JVM varaa Java-ohjelmaa suoritettaessa.
Ohjelmalaskuri: Se on pieni muistitila ja on säikeen parhaillaan suorittaman tavukoodikäskyn osoite. Jos säie suorittaa alkuperäistä menetelmää, tämän laskurin arvo on määrittelemätön.
Java-virtuaalikonepino: Jokainen säiete luo luodessaan virtuaalikonepinon, jota käytetään säikeen paikallisen muuttujataulukon, operandikehyksen, dynaamisen linkin, menetelmän poistumistietojen jne. tallentamiseen. Java-virtuaalikonepino sisältää useita pinokehyksiä. Prosessi jokaisesta kutsutusta menetelmästä suorituksen loppuun vastaa prosessia pinokehyksen työntämisestä pinoon virtuaalikoneen.
Alkuperäinen menetelmäpino: Se on JVM:n valmistama tila alkuperäisten menetelmien suorittamiseen. Se on samanlaiset toiminnot kuin Java-virtuaalikonepino. Se on muistimalli, joka kuvaa natiivimenetelmien ajoprosessia.
Keko: käytetään lähes kaikkien objektiinstanssien ja -taulukoiden tallentamiseen, ja se on pääalue, jossa roskakeräys toimii.
Menetelmäalue: käytetään luokkatietojen, vakioiden, staattisten muuttujien, just-in-time-kääntäjän kääntämän koodin jne. tallentamiseen, jonka JVM lataa. Ennen JDK1.8:aa se toteutettiin pysyvänä sukupolvena. JDK1.8:sta alkaen pysyvä sukupolvi korvataan alkuperäisellä tilalla. Metaspace käyttää paikallista muistia keomuistin sijaan.
3. Mitä tietoja pinoon ja pinoon on tallennettu?
Vastaus: Pinoon tallennetut tiedot (Java-virtuaalikonepino):
Paikallinen muuttujataulukko: Käytetään pääasiassa menetelmän parametrien ja paikallisten muuttujien tallentamiseen. Tietotyyppejä ovat perustietotyypit ja objektiviitteet.
Operandipino: käytetään tilapäisesti toimintokäskyjen ja välitulosten tallentamiseen menetelmän suorittamisen aikana.
Dynaaminen linkki: Viittaus sen luokan vakiovarastoon, johon menetelmä kuuluu, jota käytetään menetelmän symboliviittausten ratkaisemiseen.
Metodin paluuosoite: tallentaa menetelmäkutsun jälkeen suoritetun seuraavan käskyn osoitteen. Kasaan tallennetut tiedot:
Objekti-ilmentymä: Ohjelman uuden avainsanan avulla luotu objektiinstanssi, mukaan lukien objektin ominaisuudet ja menetelmät.
Taulukko: Kaikentyyppiset taulukot, mukaan lukien perustyyppiset taulukot ja objektitaulukot.
4. Miksi pysyvä sukupolvi (PermGen) pitäisi korvata metaavaruudella (MetaSpace)?
Vastaus: Pysyvän sukupolven korvaaminen metaavaruudella on pääasiassa ratkaisemaan joitain pysyvän sukupolven luontaisia ongelmia ja rajoituksia sekä parantamaan JVM:n suorituskykyä ja joustavuutta.
Paranna muistinhallinnan joustavuutta ja tehokkuutta: Pysyvän sukupolven muistin koko asetetaan, kun JVM käynnistetään, eikä sitä voida säätää dynaamisesti. Metaspace käyttää paikallista muistia Java-kekomuistin sijaan, ja sen kokoa voidaan säätää dynaamisesti tarpeen mukaan.
Ratkaise luokan purkamisen ja jätteenkeräyksen ongelma: pysyvän sukupolven GC-käyttäytyminen on monimutkaista ja arvaamatonta, ja kierrätyksen tehokkuus on alhainen.
Paranna suorituskykyä ja vakautta: Metatilan käyttö tekee JVM-muistinhallinnasta yhtenäisemmän ja johdonmukaisemman, koska metatilaa, kuten muitakin muistialueita, hallitaan paikallisen muistin avulla. Tämä yksinkertaistaa muistinhallintastrategioita ja parantaa yleistä suorituskykyä ja vakautta.
Yksinkertaista JVM-muistin hallintaa
5. Ymmärrätkö kasatilan perusrakenteen? Missä olosuhteissa esine tulee vanhaan sukupolveen?
Vastaus: Kasatilan perusrakenne koostuu pääosin uudesta sukupolvesta, vanhasta sukupolvesta ja pysyvästä sukupolvesta. JDK8:n jälkeen pysyvä sukupolvi korvataan metaavaruudella ja käyttää paikallista muistia tallentamiseen.
Cenozoic sukupolvi: Uuden sukupolven edistyminen on jaettu Eedenin alueelle ja kahteen selviytymisalueeseen (Survivor 0 ja Survivor 1)
Eden-alue: Uudet objektit varaavat ensin muistin Eden-alueella.
Selviytymisalue (S0, S1): käytetään uuden sukupolven roskienkeräyksestä selvinneiden esineiden säilyttämiseen. Jokaisen Minor GC:n jälkeen säilyneet esineet kopioidaan edestakaisin näiden kahden alueen välillä.
Vanha sukupolvi: Objektit, jotka ovat edelleen elossa useiden Minor GC: n jälkeen. Jätekeräystä (Major GC tai Full GC) tehdään harvemmin vanhassa sukupolvessa.
Pysyvä sukupolvi/metatila: käytetään luokkien metatietojen tallentamiseen, mukaan lukien luokkamääritykset, vakiot, staattiset muuttujat, juuri-in-time käännetty koodi jne.
Tilanne, kun esine on vanhassa sukupolvessa:
Ikäraja saavutetaan: Jokaisella esineellä on ikä, jolloin muisti varataan uudessa sukupolvessa, ja ikää korotetaan 1:llä jokaisen Minor GC:n jälkeen. Kun ikä saavuttaa tietyn kynnyksen (oletus on 15), kohde ylennetään vanhaan sukupolveen.
Suuri objekti: Jos objekti on liian suuri ja ylittää JVM:n asettaman kynnyksen, objekti varaa suoraan tilaa vanhassa sukupolvessa.
Riittämätön tila selviytymisalueella: Jos selviytymisalueella ei ole tarpeeksi tilaa kaikille eloon jääneille esineille Minor GC:n aikana, nämä kohteet
Dynaaminen objektin iän määritys: Jos kaikkien Survivor-tilassa olevien samanikäisten esineiden koko ylittää puolet Survivor-avaruudesta, niin esineet, joiden ikä on suurempi tai yhtä suuri kuin tämä ikä, voivat siirtyä suoraan vanhaan sukupolveen.
// 动态年龄计算代码
uint ageTable::compute_tenuring_threshold(size_t survivor_capacity){//survivor_capacity是survivor空间的大小size_t desired_survivor_size =(size_t)((((double) survivor_capacity)*TargetSurvivorRatio)/100);//TargetSurvivorRatio 为50size_t total =0;
uint age =1;while(age < table_size){
total += sizes[age];//sizes数组是每个年龄段对象大小if(total > desired_survivor_size)break;
age++;}
uint result = age < MaxTenuringThreshold ? age : MaxTenuringThreshold;...}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
6. Mille muistialueelle on sijoitettu suuria esineitä?
Vastaus: Suuret objektit (erittäin suuret taulukot ja merkkijonot) allokoidaan yleensä suoraan vanhan sukupolven muistialueelle.Tämä estää uutta sukupolvea esiintymästä useinRoskakokoelmaTällä hetkellä suuria esineitä kopioidaan usein Eden-alueen ja Survivor-alueen välillä, mikä parantaa jätteenkeräyksen tehokkuutta. Määritä kynnys suurille kohteille siirtyäksesi suoraan vanhaan sukupolveen:
Jos luokkaa ei ole ladattu, yhdistetty ja alustettu, JVM lataa luokan ensin. Tämä sisältää seuraavat vaiheet:
Lataaminen: Lue luokkatiedosto luokkalataimen kautta ja lataa luokan tavukoodi muistiin.
Yhteys: sisältää kolme vaihetta: varmennus, valmistelu ja jäsentäminen. Tarkista luokkatiedostojen oikeellisuus, valmistele luokan staattiset muuttujat ja varaa muistia sekä ratkaise symboliviittaukset suoriksi viittauksiksi.
Alustus: Suorita luokan staattinen alustuslohko ja staattisten muuttujien alustus.
muistin varaus
JVM varaa muistia kasan uusille objekteille. Varatun muistin koon määrää objektin rakenne, mukaan lukien kohteen otsikko ja ilmentymätiedot.
JVM:llä on kaksi päätapaa varata muistia:
Muistiosoitin: Jos kasamuisti on säännöllinen, allokointiosoittimen tarvitsee siirtää vain tietty etäisyys vapaaseen muistialueeseen.
Vapaa lista: Jos keon muisti on epäsäännöllinen, JVM:n on ylläpidettävä vapaata luetteloa ja löydettävä vapaasta luettelosta sopiva lohko muistia varattaessa.
alusta nollaan
JVM alustaa kaikki objektin ilmentymämuuttujat oletusarvoihinsa. Esimerkiksi numeeriset tyyppimuuttujat alustetaan arvoon 0, Boolen tyyppiset muuttujat arvoon false ja viitetyyppiset muuttujat nollaksi.
Aseta objektin otsikko
Aseta objektin otsikkotiedot objektin muistitilaan, joka sisältää objektin hash-koodin, GC-sukupolven iän, lukon tilalipun, säikeen ylläpitämän lukon, puolueellisen säikeen tunnuksen jne.
Rakentajan alustus
Kutsu objektin rakentaja suorittaaksesi objektin alustuksen loppuun. Tämä sisältää eksplisiittisten alustusoperaatioiden suorittamisen ilmentymämuuttujille sekä koodille rakentajan rungossa. Tarkat vaiheet ovat seuraavat:
Suorita luokan ilmentymän alustuslohko.
Suorita emoluokan konstruktorimetodi ylhäältä alas periytymishierarkian mukaisesti.
Alusta ilmentymämuuttujat eksplisiittisesti määritettyihin arvoihin.