내 응용 프로그램의 경우 Java 프로세스에서 사용하는 메모리는 힙 크기보다 훨씬 큽니다.
컨테이너가 실행중인 시스템은 컨테이너가 힙 크기보다 훨씬 많은 메모리를 차지하기 때문에 메모리 문제가 발생하기 시작합니다.
힙 크기는 128MB ( -Xmx128m -Xms128m
)로 설정되고 컨테이너는 최대 1GB의 메모리를 차지합니다. 정상적인 상태에서는 500MB가 필요합니다. 도커 컨테이너의 제한이 아래 (예 :) 인 경우 mem_limit=mem_limit=400MB
프로세스는 OS의 메모리 부족 킬러에 의해 종료됩니다.
Java 프로세스가 힙보다 더 많은 메모리를 사용하는 이유를 설명해 주시겠습니까? Docker 메모리 제한의 크기를 올바르게 조정하는 방법은 무엇입니까? Java 프로세스의 오프 힙 메모리 풋 프린트를 줄이는 방법이 있습니까?
JVM의 기본 메모리 추적에서 명령을 사용하여 문제에 대한 세부 정보를 수집 합니다.
호스트 시스템에서 컨테이너가 사용하는 메모리를 얻습니다.
$ docker stats --no-stream 9afcb62a26c8
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
9afcb62a26c8 xx-xxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.0acbb46bb6fe3ae1b1c99aff3a6073bb7b7ecf85 0.93% 461MiB / 9.744GiB 4.62% 286MB / 7.92MB 157MB / 2.66GB 57
컨테이너 내부에서 프로세스에서 사용하는 메모리를 얻습니다.
$ ps -p 71 -o pcpu,rss,size,vsize
%CPU RSS SIZE VSZ
11.2 486040 580860 3814600
$ jcmd 71 VM.native_memory
71:
Native Memory Tracking:
Total: reserved=1631932KB, committed=367400KB
- Java Heap (reserved=131072KB, committed=131072KB)
(mmap: reserved=131072KB, committed=131072KB)
- Class (reserved=1120142KB, committed=79830KB)
(classes #15267)
( instance classes #14230, array classes #1037)
(malloc=1934KB #32977)
(mmap: reserved=1118208KB, committed=77896KB)
( Metadata: )
( reserved=69632KB, committed=68272KB)
( used=66725KB)
( free=1547KB)
( waste=0KB =0.00%)
( Class space:)
( reserved=1048576KB, committed=9624KB)
( used=8939KB)
( free=685KB)
( waste=0KB =0.00%)
- Thread (reserved=24786KB, committed=5294KB)
(thread #56)
(stack: reserved=24500KB, committed=5008KB)
(malloc=198KB #293)
(arena=88KB #110)
- Code (reserved=250635KB, committed=45907KB)
(malloc=2947KB #13459)
(mmap: reserved=247688KB, committed=42960KB)
- GC (reserved=48091KB, committed=48091KB)
(malloc=10439KB #18634)
(mmap: reserved=37652KB, committed=37652KB)
- Compiler (reserved=358KB, committed=358KB)
(malloc=249KB #1450)
(arena=109KB #5)
- Internal (reserved=1165KB, committed=1165KB)
(malloc=1125KB #3363)
(mmap: reserved=40KB, committed=40KB)
- Other (reserved=16696KB, committed=16696KB)
(malloc=16696KB #35)
- Symbol (reserved=15277KB, committed=15277KB)
(malloc=13543KB #180850)
(arena=1734KB #1)
- Native Memory Tracking (reserved=4436KB, committed=4436KB)
(malloc=378KB #5359)
(tracking overhead=4058KB)
- Shared class space (reserved=17144KB, committed=17144KB)
(mmap: reserved=17144KB, committed=17144KB)
- Arena Chunk (reserved=1850KB, committed=1850KB)
(malloc=1850KB)
- Logging (reserved=4KB, committed=4KB)
(malloc=4KB #179)
- Arguments (reserved=19KB, committed=19KB)
(malloc=19KB #512)
- Module (reserved=258KB, committed=258KB)
(malloc=258KB #2356)
$ cat /proc/71/smaps | grep Rss | cut -d: -f2 | tr -d " " | cut -f1 -dk | sort -n | awk '{ sum += $1 } END { print sum }'
491080
이 응용 프로그램은 36MB의 뚱보 안에 번들로 포함 된 Jetty / Jersey / CDI를 사용하는 웹 서버입니다.
다음 버전의 OS 및 Java가 사용됩니다 (컨테이너 내부). Docker 이미지는 openjdk:11-jre-slim
.
$ java -version
openjdk version "11" 2018-09-25
OpenJDK Runtime Environment (build 11+28-Debian-1)
OpenJDK 64-Bit Server VM (build 11+28-Debian-1, mixed mode, sharing)
$ uname -a
Linux service1 4.9.125-linuxkit #1 SMP Fri Sep 7 08:20:28 UTC 2018 x86_64 GNU/Linux
https://gist.github.com/prasanthj/48e7063cac88eb396bc9961fb3149b58
cgroups
커널에 의해 처리되고 사용자 프로그램에서 보이지 않더라도 사용 된 메모리에 디스크 캐시 가 추가 된다는 것을 알아야합니다 . (당신이 명령 ps
하고 docker stats
디스크 캐시를 계산하지 마십시오.)