Direkt zum Inhalt

Wie exportiere ich eine Java-Heap-Dump-Datei in einen S3-Bucket?

Lesedauer: 4 Minute
0

Ich habe einen Fehler "heap out of memory" in meiner Java-Anwendung erhalten, die in Amazon Elastic Container Service (Amazon ECS) gespeichert ist. Um den Fehler zu beheben, möchte ich eine HPROF-Datei erstellen und sie in einem Amazon Simple Storage Service (Amazon S3)-Bucket speichern.

Kurzbeschreibung

Der häufigste Grund, warum du eine OutOfMemoryError-Ausnahme erhältst, ist, dass eine Java Virtual Machine (JVM) einem Heap nicht genügend Speicher zuweisen kann. Wenn eine Java-Anwendung in einem ECS-Container ausgeführt wird, wird die Anwendung durch einen Fehler "heap out of memory" unterbrochen und ECS-Aufgaben werden gestoppt. Jegliche .hprof-Dateien, die die Anwendung speichert, sind nicht mehr verfügbar. Um den Ausnahmefehler zu beheben und Probleme mit der Speicherzuweisung zu debuggen, musst du eine HPROF-Datei erstellen und in einem S3-Bucket speichern.

Lösung

Hinweis: Die folgende Lösung behebt die meisten OutOfMemoryError-Ausnahmeszenarien. Weitere Informationen zur Ursache von Java-Speicherfehlern findest du unter OutOfMemoryError-Ausnahmen verstehen auf der Oracle-Website.

Einen S3-Bucket erstellen

Verwende die Amazon S3-Konsole, um einen S3-Bucket zu erstellen, für das Speichern der .hprof-Datei.

Eine ECS-Aufgabendefinition erstellen

Verwende die Amazon ECS-Konsole, um eine Aufgabendefinition als Blueprint für die Java-Anwendung zu erstellen.

Gib für die Umgebungsvariable den Namen des S3-Buckets an. Die Initialisierungsbefehle der Anwendung verwenden ebenfalls den S3-Bucket-Namen.

Hinweis: HEAP_DUMP_BUCKET ist die Umgebungsvariable in den Beispielbefehlen.

Eine IAM-Rolle für ECS-Aufgaben erstellen

Erstelle eine AWS Identity and Access Management (IAM)-Rolle für ECS-Aufgaben, die s3:PutObject-Berechtigungen enthält, damit du Dateien hochladen kannst.

Die Initialisierungsbefehle ausführen

Im JVM-Arbeitsverzeichnis wird ein Standard-Heap-Dump in einer Datei mit dem Namen java_pidpid.hprof erstellt. Um einen anderen Dateinamen oder ein anderes Verzeichnis anzugeben, verwende die Option XX:HeapDumpPath=.

Der Heap-Dump wird im Verzeichnis /tmp/heap_dump.hprof in den folgenden Beispielinitialisierungsbefehlen generiert:

CMD ["java", \
    "-XX:+HeapDumpOnOutOfMemoryError", \
    "-XX:HeapDumpPath=/tmp/heap_dump.hprof", \
    "-XX:OnOutOfMemoryError=yum install -y aws-cli > /dev/null && aws s3 mv /tmp/heap_dump.hprof s3://$HEAP_DUMP_BUCKET/'date+%F_%T'.hprof ; kill -9 %p", \
    "MemoryApp" \]

Beispiel für einen Initialisierungsbefehlsablauf

**Hinweis:**Wenn bei der Ausführung von AWS Command Line Interface (AWS CLI)-Befehlen Fehler auftreten, findest du weitere Informationen unter Troubleshoot AWS CLI errors. Stelle außerdem sicher, dass du die neueste Version der AWS CLI verwendest.

Die OnOutOfMemoryError-Option gibt einen Befehl oder ein Skript an, das ausgeführt wird, wenn eine OutOfMemoryError-Ausnahme auftritt. Weitere Informationen zur OnOutOfMemoryError-Option findest du unter Java HotSpot VM-Befehlszeilenoptionen auf der Oracle-Website.

Führe die folgenden Schritte für den OnOutOfMemoryError-Befehlsablauf aus:

  1. Installiere das AWS Command Line Interface (AWS CLI) innerhalb von**-y** ohne Interaktion. Die Befehlsausgabe wird in einer temporären Datei in /dev/null gespeichert, sodass den Container-Protokollen keine unnötigen Informationen über die AWS-CLI-Installation hinzugefügt werden.
  2. Lade die .hprof-Datei mit den Berechtigungen der ECS-Aufgabenrolle in den S3-Bucket hoch. Die .hprof-Datei wurde umbenannt, sodass sie dem date+%F_%T.hprof-Muster folgt.
  3. Überprüfe die Amazon CloudWatch-Protokolldaten:
    2023-05-02T17:02:37.748+01:00    Hello, world! Hello Java! Good bye memory...
    2023-05-02T17:02:37.748+01:00    Going to sleep for 2 ms...
    2023-05-02T17:02:39.748+01:00    Wake now, lets heap the memory...
    2023-05-02T17:02:39.748+01:00    java.lang.OutOfMemoryError: Requested array size exceeds VM limit
    2023-05-02T17:02:39.748+01:00    Dumping heap to /tmp/heap_dump.hprof ...
    2023-05-02T17:02:39.756+01:00    Heap dump file created [2893599 bytes in 0.008 secs]
    2023-05-02T17:02:39.756+01:00    #
    2023-05-02T17:02:39.757+01:00    # java.lang.OutOfMemoryError: Requested array size exceeds VM limit
    2023-05-02T17:02:39.757+01:00    # -XX:OnOutOfMemoryError="yum install -y aws-cli > /dev/null && aws s3 mv /tmp/heap_dump.hprof s3://$HEAP_DUMP_BUCKET/`date +%F_%T`.hprof ; kill -9 %p"
    2023-05-02T17:02:39.757+01:00    # Executing /bin/sh -c "yum install -y aws-cli > /dev/null && aws s3 mv /tmp/heap_dump.hprof s3://$HEAP_DUMP_BUCKET/`date +%F_%T`.hprof "...
    2023-05-02T17:02:54.663+01:00    Completed 256.0 KiB/2.8 MiB (2.2 MiB/s) with 1 file(s) remaining
    Completed 512.0 KiB/2.8 MiB (4.4 MiB/s) with 1 file(s) remaining
    Completed 768.0 KiB/2.8 MiB (6.6 MiB/s) with 1 file(s) remaining
    Completed 1.0 MiB/2.8 MiB (8.7 MiB/s) with 1 file(s) remaining
    Completed 1.2 MiB/2.8 MiB (10.8 MiB/s) with 1 file(s) remaining
    Completed 1.5 MiB/2.8 MiB (12.9 MiB/s) with 1 file(s) remaining
    Completed 1.8 MiB/2.8 MiB (15.0 MiB/s) with 1 file(s) remaining
    Completed 2.0 MiB/2.8 MiB (17.0 MiB/s) with 1 file(s) remaining
    Completed 2.2 MiB/2.8 MiB (19.1 MiB/s) with 1 file(s) remaining
    Completed 2.5 MiB/2.8 MiB (21.1 MiB/s) with 1 file(s) remaining
    Completed 2.8 MiB/2.8 MiB (23.1 MiB/s) with 1 file(s) remaining
    Completed 2.8 MiB/2.8 MiB (13.0 MiB/s) with 1 file(s) remaining move: ../tmp/heap_dump.hprof to s3://fargate-test-cluster-logs/2023-05-02_16:02:53.hprof
    2023-05-02T17:02:54.705+01:00    Executing /bin/sh -c "kill -9 1"...
    2023-05-02T17:02:54.707+01:00    Exception in thread "main" java.lang.OutOfMemoryError: Requested array size exceeds VM limit
    2023-05-02T17:02:54.707+01:00    at MemoryApp.main(MemoryApp.java:13)

Im vorherigen Beispiel für Protokolldaten wird yum install für die AWS-CLI in einem Container verwendet, der das Amazon Corretto 17-Image ausführt. Wenn das Container-Image auf einem anderen Betriebssystem (OS) basiert, ändert sich der Befehl. Im Folgenden findest du Beispielbefehle für verschiedene Betriebssysteme:

  • Fedora Linux: dnf install -y awscli
  • Debian: apt-get install -y awscli
  • Alpine Linux: apk add aws-cli

Hinweis: Bei jedem Betriebssystem musst du einen Befehl verwenden, der dem Beispielbefehl yum install entspricht, mit dem die AWS-CLI installiert wird.