Sobes.tech
Junior

Czym jest Out of Memory (OOM)?

sobes.tech AI

Odpowiedź od AI

Out of Memory (OOM) — to sytuacja, gdy aplikacja lub system operacyjny wyczerpuje dostępną pamięć RAM na przydzielenie nowych obiektów lub wykonanie wymaganych operacji.

W kontekście systemów operacyjnych, OOM występuje, gdy system nie może przydzielić pamięci dla nowego procesu lub wątku. Aby zapobiec całkowitemu awarii systemu, w Linuxie istnieje OOM Killer — mechanizm, który wymusza zakończenie procesów zużywających dużo pamięci, aby zwolnić zasoby.

W kontekście aplikacji, OOM pojawia się, gdy maszyna wirtualna Java (JVM) lub inne środowisko wykonawcze nie może przydzielić pamięci w stercie (heap) do utworzenia nowego obiektu.

Przyczyny OOM mogą być różne:

  • Wycieki pamięci: Obiekty, które nie są już używane, pozostają w pamięci, ponieważ istnieją odwołania do nich, uniemożliwiając garbage collectorowi ich usunięcie.
  • Nadmierne zużycie pamięci: Aplikacja żąda lub utrzymuje zbyt dużą ilość pamięci do przetwarzania danych (np. ładowanie dużego pliku do pamięci).
  • Niewystarczające przydzielenie pamięci: Ustawienia JVM (np. -Xmx) lub konfiguracja środowiska wykonawczego nie zapewniają wystarczającej ilości pamięci dla aplikacji.
  • Nieprawidłowa konfiguracja pul wątków lub połączeń: Nadmiar aktywnych wątków lub połączeń może zużywać znaczne ilości pamięci stosu (dla wątków) lub innych obszarów pamięci.

Charakterystyczne objawy OOM na poziomie aplikacji:

  • Spowolnienie działania aplikacji.
  • Wyjątek OutOfMemoryError w logach.
  • Spadek wydajności garbage collectora.

Diagnostyka OOM obejmuje:

  • Analiza logów: Szukanie wyjątków OutOfMemoryError i komunikatów OOM Killer.
  • Zrzuty sterty (Heap Dumps): Tworzenie migawki zawartości sterty w momencie wystąpienia błędu do analizy za pomocą narzędzi (np. Eclipse Memory Analyzer Tool (MAT), VisualVM).
  • Monitorowanie: Użycie systemów monitorowania (Prometheus, Grafana, New Relic) do śledzenia zużycia pamięci JVM i systemu operacyjnego.
  • Profilowanie: Użycie profilerów (JProfiler, YourKit) do wykrywania wzorców użycia pamięci i źródeł wycieków.
// Przykład kodu Java, który może prowadzić do OOM (z wyciekiem pamięci)
import java.util.ArrayList;
import java.util.List;

public class OOMExample {
    private List<Object> largeList = new ArrayList<>();

    public void addObjects() {
        while (true) {
            largeList.add(new Object()); // Ciągłe dodawanie obiektów bez ich usuwania
        }
    }

    public static void main(String[] args) {
        OOMExample example = new OOMExample();
        example.addObjects();
    }
}
# Przykład polecenia do uruchomienia Java z limitem pamięci dla szybkiej demonstracji OOM
java -Xmx64m OOMExample

Zapobieganie OOM obejmuje:

  • Optymalizację kodu pod kątem efektywnego wykorzystania pamięci.
  • Poprawne ustawienie parametrów pamięci JVM lub środowiska wykonawczego.
  • Regularną analizę zrzutów sterty i profilowanie.
  • Monitorowanie zużycia pamięci w środowisku produkcyjnym.