Teknologian jakaminen

Haastattelukysymys 005-Java-JVM (Osa 1)

2024-07-12

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

Haastattelukysymys 005-Java-JVM (Osa 1)

Itsetestauskysymykset

  • 1. Mistä osista JVM koostuu?
  • 2. Mitä alueita suoritusaikatietoalue sisältää?
  • 3. Mitä tietoja pinoon ja pinoon on tallennettu?
  • 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.
    Java-virtuaalikoneen ajonaikainen tietoalue

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 为50
size_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:

# 将大于1MB的对象直接分配在老年代
java -XX:PretenureSizeThreshold=1m -jar your-application.jar
  • 1
  • 2

7. Mikä on Java-objektien luontiprosessi?

vastaus:

  1. Luokan lataustarkastus
    • 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.
  2. 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.
  3. alusta nollaan
    • JVM alustaa kaikki objektin ilmentymämuuttujat oletusarvoihinsa. Esimerkiksi numeeriset tyyppimuuttujat alustetaan arvoon 0, Boolen tyyppiset muuttujat arvoon false ja viitetyyppiset muuttujat nollaksi.
  4. 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.
  5. 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.
      • Suorita luokan konstruktorimetodin pääosa.
/**
 * 创建对象的示例代码
 */
public class MyClass {
    private int value;

    public MyClass(int value) {
        this.value = value;
    }

    public static void main(String[] args) {
        MyClass obj = new MyClass(10);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • Yllä olevan koodiesimerkin suoritusprosessi on seuraava:
    • Luokan lataus: JVM tarkistaa, onko MyClass ladattu. Jos sitä ei ladata, MyClass-luokka ladataan.
    • Muistin varaus: Varaa muistia keon uudelle MyClass-esiintymälle.
    • Muistin alustus: Alusta varattu muisti oletusarvoihin.
    • Aseta objektin otsikko: Aseta metatiedot objektin otsikkoon.
    • Rakentajan alustus: Suorita MyClass-konstruktori ja alusta ilmentymän muuttujan arvoksi 10.

Viitteet