Megosztás a következőn keresztül:


Java-memóriakezelés

Feljegyzés

Az Azure Spring Apps az Azure Spring Cloud szolgáltatás új neve. Bár a szolgáltatásnak új neve van, bizonyos helyeken a régi nevet fogja látni egy darabig, miközben az eszközök, például képernyőképek, videók és diagramok frissítésével dolgozunk.

Ez a cikk a következőre vonatkozik: ✔️ Basic/Standard ✔️ Enterprise

Ez a cikk a Java-memóriakezeléssel kapcsolatos különböző fogalmakat ismerteti, amelyek segítenek megérteni az Azure Spring Appsben üzemeltetett Java-alkalmazások viselkedését.

Java memóriamodell

A Java-alkalmazások memóriája több részből áll, és különböző módokon oszthatók el a részek. Ez a cikk a Java-memóriát ismerteti halommemória, nem halommemória és közvetlen memória szerint.

Halommemória

A halommemória az összes osztálypéldányt és tömböt tárolja. Minden Java virtuális gép (JVM) csak egy halomterülettel rendelkezik, amely a szálak között van megosztva.

A Spring Boot Actuator megfigyelheti a halommemória értékét. A Spring Boot Actuator a halomértéket jvm.memory.used/committed/maxa . További információ: jvm.memory.used /committed/max szakasz az Eszközökben a memóriaproblémák elhárításához.

A halommemória a fiatal és az öreg generációra oszlik. Ezeket a kifejezéseket a következő listában, valamint a kapcsolódó kifejezésekben ismertetjük.

  • Fiatal generáció: minden új objektumot fiatal generációban osztanak ki és érnek el.

    • Eden space: az új objektumok az Eden térben vannak lefoglalva.
    • Túlélőtér: az objektumok át lesznek helyezve az Edenből a túlélő térbe egy szemétgyűjtési ciklus túlélése után. A túlélőtér két részre osztható: s1 és s2.
  • Régi generáció: más néven kiterített tér. Azokat a tárgyakat, amelyek hosszú ideig a túlélő terekben maradtak, át lesznek helyezve a régi generációba.

A Java 8 előtt egy másik, állandó generációnak nevezett szakasz is része volt a halomnak. A Java 8-tól kezdve az állandó generációt a nem halommemória metatere váltotta fel.

Nem halommemória

A nem halommemória a következő részekre oszlik:

  • A nem halommemória azon része, amely a Java 8-tól kezdve az állandó generációt (vagy permGent) váltotta fel. A Spring Boot Actuator megfigyeli ezt a szakaszt, és a jvm.memory.used/committed/max. Más szóval jvm.memory.used/committed/max a halommemória és a nem halommemória egykori permGen része. Az egykori állandó generáció a következő részekből áll:

    • Az osztálybetöltők által betöltött osztálydefiníciókat tároló Metaspace.
    • Tömörített osztálytér, amely a tömörített osztálymutatókhoz használható.
    • A JIT által lefordított natív kódot tároló kódgyorsítótár.
  • Más memória, például a szálverem, amelyet a Spring Boot Actuator nem figyel meg.

Közvetlen memória

A közvetlen memória a natív memória java.nio.DirectByteBuffer, amelyet harmadik féltől származó kódtárak, például nio és gzip használnak.

A Spring Boot Actuator nem figyeli meg a közvetlen memória értékét.

Az alábbi ábra az előző szakaszban ismertetett Java-memóriamodellt foglalja össze.

A Java-memóriamodellt bemutató diagram.

Java-szemétgyűjtés

A Java-szemétgyűjtés (GC) három kifejezésből áll: "Minor GC", "Major GC" és "Full GC". Ezek a kifejezések nincsenek egyértelműen definiálva a JVM-specifikációban. Itt a "Fő GC" és a "Teljes GC" egyenértékűnek tekinthető.

A kisebb GC akkor működik, ha az Éden-terület megtelt. Eltávolítja a fiatal generáció összes halott objektumát, és az élő objektumokat az Eden térről a túlélők s1 területére, vagy s1-ről s2-re helyezi át.

A teljes GC vagy fő csoportházirend-objektum a teljes halomban végez szemétgyűjtést. A teljes GC olyan részeket is képes gyűjteni, mint a metatér és a közvetlen memória, amelyeket csak teljes GC-vel lehet megtisztítani.

A halom maximális mérete befolyásolja a kisebb GC és a teljes GC gyakoriságát. A maximális metatér és a maximális közvetlen memóriaméret befolyásolja a teljes GC-t.

Ha a halom maximális méretét alacsonyabb értékre állítja, gyakrabban fordulnak elő szemétgyűjtések, ami kissé lelassítja az alkalmazást, de jobban korlátozza a memóriahasználatot. Ha a maximális halomméretet magasabb értékre állítja, a szemétgyűjtések ritkábban fordulnak elő, ami nagyobb memóriahiányt (OOM) okozhat. További információ: Az alkalmazás újraindításával kapcsolatos problémák memóriakihasználtság miatti problémáinak típusai című szakasz.

A metatér és a közvetlen memória csak teljes GC-vel gyűjthető össze. Ha a metatér vagy a közvetlen memória megtelt, teljes GC lesz.

Java-memóriakonfigurációk

A következő szakaszok a Java memóriakonfigurációjának fontos szempontjait ismertetik.

Java-tárolók

Az Azure Spring Apps-alkalmazások tárolókörnyezetekben futnak. További információ: Java-alkalmazások tárolóba helyezése.

Fontos JVM-beállítások

A memória egyes részeinek maximális méretét JVM-beállításokkal konfigurálhatja. A JVM-beállításokat az Azure CLI-parancsokkal vagy az Azure Portalon állíthatja be. További információkért tekintse meg a Konfigurációk módosítása a memóriaproblémák elhárításához szükséges eszközök című szakaszt.

Az alábbi lista a JVM-beállításokat ismerteti:

  • Halomméret konfigurálása

    • -Xms a kezdeti halomméretet abszolút érték szerint állítja be.
    • -Xmx a maximális halomméretet abszolút érték szerint állítja be.
    • -XX:InitialRAMPercentage A kezdeti halomméretet a halomméret /alkalmazás memóriaméretének százalékával állítja be.
    • -XX:MaxRAMPercentage A maximális halomméretet a halomméret /alkalmazás memóriaméretének százalékával állítja be.
  • Közvetlen memóriaméret konfigurálása

    • -XX:MaxDirectMemorySize a közvetlen memória maximális méretét adja meg abszolút érték szerint. További információ: MaxDirectMemorySize az Oracle dokumentációjában.
  • Metatér méretkonfigurációja

    • -XX:MaxMetaspaceSize a metatér maximális méretét abszolút érték szerint állítja be.

Alapértelmezett maximális memóriaméret

Az alábbi szakaszok bemutatják, hogyan van beállítva az alapértelmezett maximális memóriaméret.

Alapértelmezett maximális halomméret

Az Azure Spring Apps az alapértelmezett maximális halommemória-méretet a Java-alkalmazások alkalmazásmemóriának körülbelül 50–80%-ára állítja be. Az Azure Spring Apps a következő beállításokat használja:

  • Ha az alkalmazás memóriája 1 GB, az alapértelmezett maximális halomméret az alkalmazásmemória < 50%-a lesz.
  • Ha 1 GB <= az alkalmazás memóriája < 2 GB, az alapértelmezett maximális halomméret az alkalmazás memóriájának 60%-a lesz.
  • Ha 2 GB <= az alkalmazás memóriája < 3 GB, az alapértelmezett maximális halomméret az alkalmazás memóriájának 70%-a lesz.
  • Ha 3 GB <= az alkalmazás memóriája, az alapértelmezett maximális halomméret az alkalmazásmemória 80%-a lesz.

A közvetlen memória alapértelmezett maximális mérete

Ha a közvetlen memória maximális mérete nincs beállítva JVM-beállításokkal, a JVM automatikusan beállítja a közvetlen memória maximális méretét a Runtime.getRuntime.maxMemory()által visszaadott értékre. Ez az érték körülbelül megegyezik a halommemória maximális méretével. További információt a JDK 8 VM.java fájlban talál.

Memóriahasználat elrendezése

A halom méretét az átviteli sebesség befolyásolja. Alapvetően a konfiguráláskor megtarthatja az alapértelmezett maximális halomméretet, ami ésszerű memóriát hagy más részek számára.

A metatér mérete a kód összetettségétől függ, például az osztályok számától.

A közvetlen memória mérete az átviteli sebességtől és a külső kódtárak, például a nio és a gzip használatától függ.

Az alábbi lista a 2 GB-os alkalmazások tipikus memóriaelrendezési mintáját ismerteti. Erre a listára hivatkozva konfigurálhatja a memóriaméret beállításait.

  • Teljes memória (2048M)
  • Halommemória: Az Xmx 1433,6 M (a teljes memória 70%-a). A napi memóriahasználat referenciaértéke 1200 M.
    • Fiatal generáció
      • Túlélőtér (S0, S1)
      • Eden szóköz
    • Régi generáció
  • Nem halommemória
    • Megfigyelt rész (a Spring Boot Actuator megfigyelte)
      • Metatér: a napi használati referenciaérték 50M-256M
      • Kódgyorsítótár
      • Tömörített osztálytér
    • Nem figyelt rész (a Spring Boot Actuator nem figyeli meg): a napi használati referenciaérték 150M-250M.
      • Szálverem
      • GC, belső szimbólum és egyéb
  • Közvetlen memória: a napi használati referenciaérték 10M-200M.

Az alábbi ábrán ugyanazok az információk láthatók. A szürke számok a napi memóriahasználat referenciaértékei.

A 2 GB-os alkalmazások jellemző memóriaelrendezésének diagramja.

Összességében a maximális memóriaméretek konfigurálásakor figyelembe kell vennie a memória egyes részeinek használatát, és az összes maximális méret összege nem haladhatja meg a teljes rendelkezésre álló memóriát.

Java OOM

Az OOM azt jelenti, hogy az alkalmazás nincs memóriában. Két különböző fogalom létezik: tároló OOM és JVM OOM. További információ: Az alkalmazás újraindításával kapcsolatos problémák, amelyeket memóriakihasználtság miatti problémák okoznak.

Lásd még