Megosztás:


Java-memóriakezelés

Megjegyzés

A Alapszintű, Standardés Enterprise tervek 2025. március 17-én nyugdíjazási időszakba léptek. További információkért lásd az Azure Spring Apps kivonási bejelentését.

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 kupacértéket a jvm.memory.used/committed/max részeként veszi figyelembe. További információkért tekintse meg a jvm.memory.used/committed/max szakaszt az Eszközök a memóriaproblémák elhárításához című részben.

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.
  • Öreg generáció: más néven előjogos tér. Azokat a tárgyakat, amelyek hosszú ideig a túlélő terekben maradtak, át lesznek helyezve az öreg 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 annak a részének tekinti a jvm.memory.used/committed/max. Más szóval, a jvm.memory.used/committed/max a halommemória és a nem halommemória korábbi permGen részének összege. 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.
  • Egyéb memória, például a szálverem, amelyet a Spring Boot Actuator nem figyel.

Közvetlen memória

A közvetlen memória az a natív memória, amelyet a java.nio.DirectByteBuffer foglal le, és amelyet harmadik féltől származó könyvtárak, például a NIO és a 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éshez (GC) három kifejezés tartozik: "Kis GC", "Nagy GC" és "Teljes 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ő GC 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ány (OOM) kockázatát rejtheti magában. További információért lásd az Memóriakihasználás miatti problémák típusai című szakaszt az Alkalmazás újraindítási problémái memóriakihasználás miatt részben.

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 beállítá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 és az alkalmazás memóriaméretének hányadával állítja be.
    • -XX:MaxRAMPercentage beállítja a maximális halomméretet a halomméret és az alkalmazás memóriaméretének százaléka alapján.
  • 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 a feldolgozási teljesítmény 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)
      • Éden tér
    • 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ód gyorsí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