Moin,
wir haben aktuell das Problem, dass einige Java-Anwendungen, die in einem Proxmox Container unter Ubuntu 24.04 laufen, einen Out-Of-Memory Error vom Linux-Kernel erhalten, bevor der Gargabe-Collector zugreifen kann.
Nach weiterer Analyse haben wir herausgefunden, dass Java nicht 1/4 des Memory-Limits des Containers als maxMemory verwendet, sondern 1/4 des Host-Memory. In unserem konkreten Fall hat der Host 128 GB RAM und der Container 4 GB RAM zugewiesen. Java denkt, es hat 32 GB zur Verfügung und füllt den RAM fleißig, bis der OOM-Killer bei 4 GB zuschlägt und die Anwendung crasht.
Die Limits können mit dem folgenden kleinen Programm angezeigt werden:
Auch der folgende Java-Befehl zeigt keine Memory-Limits vom Provider: cgroupv2 an:
Die weitere Analyse zeigt, dass der Wert in memory.max im cgroup2-mount nicht korrekt befüllt ist:
Auf dem Host wird der memory.max für den LXC-Container aber korrekt befüllt
Zum Vergleich die Ausgabe von memory.max von podman unter Fedora 40. Hier zeigt Java auch die korrekten Memory-Limits an.
Handelt es sich hierbei um einen Bug in Proxmox/LXC, oder ist das expected-behaviour?
Version: pve-manager/8.2.4/faa83925c9641325 (running kernel: 6.8.8-1-pve)
wir haben aktuell das Problem, dass einige Java-Anwendungen, die in einem Proxmox Container unter Ubuntu 24.04 laufen, einen Out-Of-Memory Error vom Linux-Kernel erhalten, bevor der Gargabe-Collector zugreifen kann.
Nach weiterer Analyse haben wir herausgefunden, dass Java nicht 1/4 des Memory-Limits des Containers als maxMemory verwendet, sondern 1/4 des Host-Memory. In unserem konkreten Fall hat der Host 128 GB RAM und der Container 4 GB RAM zugewiesen. Java denkt, es hat 32 GB zur Verfügung und füllt den RAM fleißig, bis der OOM-Killer bei 4 GB zuschlägt und die Anwendung crasht.
Die Limits können mit dem folgenden kleinen Programm angezeigt werden:
Code:
public class Main {
// Ausgabe:
// 30208
// 2025
// 2032
public static void main(String[] args) {
Runtime runtime = Runtime.getRuntime();
System.out.println(runtime.maxMemory() / 1024 / 1024);
System.out.println(runtime.freeMemory() / 1024 / 1024);
System.out.println(runtime.totalMemory() / 1024 / 1024);
}
}
Auch der folgende Java-Befehl zeigt keine Memory-Limits vom Provider: cgroupv2 an:
Code:
# java -XshowSettings:system -version
Operating System Metrics:
Provider: cgroupv2
Effective CPU Count: 2
CPU Period: -1
CPU Quota: -1
CPU Shares: -1
List of Processors: N/A
List of Effective Processors: N/A
List of Memory Nodes: N/A
List of Available Memory Nodes: N/A
Memory Limit: Unlimited
Memory Soft Limit: 0.00K
Memory & Swap Limit: Unlimited
Maximum Processes Limit: 154442
openjdk version "21.0.3" 2024-04-16
OpenJDK Runtime Environment (build 21.0.3+9-Ubuntu-1ubuntu122.04.1)
OpenJDK 64-Bit Server VM (build 21.0.3+9-Ubuntu-1ubuntu122.04.1, mixed mode, sharing)
Die weitere Analyse zeigt, dass der Wert in memory.max im cgroup2-mount nicht korrekt befüllt ist:
Code:
# cat /sys/fs/cgroup/memory.max
max
Auf dem Host wird der memory.max für den LXC-Container aber korrekt befüllt
Code:
# cat /sys/fs/cgroup/lxc/117/memory.max
4294967296
Zum Vergleich die Ausgabe von memory.max von podman unter Fedora 40. Hier zeigt Java auch die korrekten Memory-Limits an.
Code:
# podman run -m=1G -it debian:latest cat /sys/fs/cgroup/memory.max
1073741824
Handelt es sich hierbei um einen Bug in Proxmox/LXC, oder ist das expected-behaviour?
Version: pve-manager/8.2.4/faa83925c9641325 (running kernel: 6.8.8-1-pve)