Dela via


Containerisera dina Java-program

Den här artikeln innehåller en översikt över rekommenderade strategier och inställningar för att containerisera Java-program. När du containeriserar ett Java-program bör du noga överväga hur mycket CPU-tid containern har tillgänglig. Fundera sedan på hur mycket minne som är tillgängligt både när det gäller den totala mängden minne och heapstorleken för den virtuella Java-datorn (JVM). I containerbaserade miljöer kan program ha åtkomst till alla processorer och därför kunna köra flera trådar parallellt. Det är dock vanligt att containrar har en cpu-kvot som kan begränsa åtkomsten till processorer.

JVM har heuristik för att fastställa antalet "tillgängliga processorer" baserat på CPU-kvoten, vilket dramatiskt kan påverka prestandan för Java-program. Det minne som allokeras till själva containern och storleken på heapområdet för JVM är lika viktigt som processorerna. Dessa faktorer avgör beteendet för skräpinsamlaren (GC) och systemets övergripande prestanda.

Containerisera ett nytt program

När du containeriserar en Java-arbetsbelastning för ett nytt program måste du ta hänsyn till två saker när du tänker på minne:

  • Det minne som allokerats till själva containern.
  • Mängden minne som är tillgängligt för Java-processen.

Förstå JVM-standardergonom

Program behöver en startpunkt och inställningar. JVM har standardergonom med fördefinierade värden som baseras på antalet tillgängliga processorer och mängden minne i systemet. Standardvärdena som visas i följande tabeller används när JVM startas utan specifika startflaggor eller parametrar.

I följande tabell visas standard-GC som används för de tillgängliga resurserna:

Tillgängliga resurser Standard-GC
Valfritt antal processorer
Upp till 1 791 MB minne
SerialGC
Över 2 processorer
1 792 MB eller mer minne
G1GC

I följande tabell visas den maximala standardstorleken för heap beroende på hur mycket minne som är tillgängligt i miljön där JVM körs:

Tillgängligt minne Standard maximal heapstorlek
Upp till 256 MB 50% tillgängligt minne
256 MB till 512 MB ~127 MB
Mer än 512 MB 25% tillgängligt minne

Standardstorleken för den initiala heapen är 1/64 tillgängligt minne. Dessa värden är giltiga för OpenJDK 11 och senare – och för de flesta distributioner, inklusive Microsoft Build of OpenJDK, Azul Zulu, Eclipse Temurin, Oracle OpenJDK och andra.

Bestämma minne för container

Välj en containerminnesmängd som passar bäst för din arbetsbelastning, beroende på programmets behov och dess distinkta användningsmönster. Om ditt program till exempel skapar stora objektdiagram behöver du förmodligen mer minne än du behöver för program med många små objektdiagram.

Tips/Råd

Om du inte vet hur mycket minne som ska allokeras är en bra startpunkt 4 GB.

Bestäm JVM heap-minne

När du allokerar JVM-heapminne behöver JVM mer minne än vad som används för JVM-heapen. När du anger det maximala JVM-heapminnet ska det aldrig vara lika med mängden containerminne eftersom det orsakar Out of Memory (OOM)-fel och containerkrascher.

Tips/Råd

Allokera 75% containerminne för JVM-heapen.

I OpenJDK 11 och senare kan du ange JVM-heapstorleken på följande sätt:

Beskrivning Flagga Exempel
Fast värde -Xmx -Xmx4g
Dynamiskt värde -XX:MaxRAMPercentage -XX:MaxRAMPercentage=75

Minsta, inledande heapstorlek

Om miljön garanterat har en viss mängd minne reserverat till en JVM-instans, till exempel i en container, bör du ange den minsta heapstorleken – eller den ursprungliga heapstorleken – till samma storlek som den maximala heapstorleken. Den här inställningen anger för JVM att den inte ska utföra uppgiften att frigöra minne till operativsystemet.

Om du vill ange en minsta heapstorlek använder du -Xms för absoluta belopp eller -XX:InitialRAMPercentage för procentbelopp.

Viktigt!

Flaggan -XX:MinRAMPercentage, trots vad namnet antyder, används för att ange den maximala STANDARD-RAM-procentandelen för system med upp till 256 MB RAM-minne tillgängligt i systemet.

Diagram som visar standardstorleken för heap på OpenJDK 17.

Avgöra vilken GC som ska användas

Tidigare fastställde du hur mycket JVM-heapminne som ska börja med. Nästa steg är att välja din GC. Mängden maximalt JVM-heapminne som du har är ofta en faktor för att välja din GC. I följande tabell beskrivs egenskaperna för varje GC.

Faktorer SerialGC ParallelGC G1GC ZGC ShenandoahGC
Antal kärnor 1 2 2 2 2
Flera trådar Nej Ja Ja Ja Ja
Java-heapstorlek <4 GByte <4 GByte >4 GByte >4 GByte >4 GByte
Paus Ja Ja Ja Ja (<1 ms) Ja (<10 ms)
Omkostnader Minimalt Minimalt Moderat Moderat Moderat
Bakhängstidseffekt Högt Högt Högt Låg Moderat
JDK-version Allt Allt JDK 8+ JDK 17+ JDK 11+
Passar bäst för Enkärniga små heapminnen Små heaps- eller batcharbetsbelastningar med flera kärnor med valfri heapstorlek Responsiv i medelstora till stora högar (begäran-svar/DB-interaktioner) Responsiv i medelstora till stora högar (begäran-svar/DB-interaktioner) Responsiv i medelstora till stora högar (begäran-svar/DB-interaktioner)

Tips/Råd

För de flesta allmänna mikrotjänstprogram börjar du med Parallell GC.

Fastställa hur många CPU-kärnor som behövs

För alla GC utom SerialGC rekommenderar vi två eller fler vCPU-kärnor – eller åtminstone 2000m för cpu_limit på Kubernetes. Vi rekommenderar inte att du väljer något mindre än en vCPU-kärna i containerbaserade miljöer.

Tips/Råd

Om du inte vet hur många kärnor du ska börja med är ett bra val två vCPU-kärnor.

Välj en startpunkt

Vi rekommenderar att du börjar med två repliker eller instanser i containerorkestreringsmiljöer som Kubernetes, OpenShift, Azure Spring Apps, Azure Container Apps och Azure App Service. I följande tabell sammanfattas de rekommenderade startpunkterna för containeriseringen av ditt nya Java-program.

vCPU-kärnor Minne för container JVM-heapstorlek GC Kopior
2 4 GB 75 % ParallelGC 2

Använd följande JVM-parametrar:

-XX:+UseParallelGC -XX:MaxRAMPercentage=75

Containerisera en befintlig applikation på plats

Om programmet redan körs lokalt eller på en virtuell dator i molnet rekommenderar vi att du börjar med följande konfiguration:

  • Samma mängd minne som programmet för närvarande har åtkomst till.
  • Samma antal processorer eller vCPU-kärnor som programmet för närvarande har tillgängligt.
  • Samma JVM-parametrar som du använder för närvarande.

Om kombinationen av vCPU-kärnor eller containerminne inte är tillgänglig väljer du den närmaste och avrundar vCPU-kärnorna och containerminnet.

Nästa steg

Nu när du förstår de allmänna rekommendationerna för att containerisera Java-program fortsätter du till följande artikel för att upprätta en containeriseringsbaslinje: