docker 容器 + java 应用程序 -> 交换使用 -> 为什么?

docker 容器 + java 应用程序 -> 交换使用 -> 为什么?

有一个docker容器,里面有java应用程序。

docker 检查 dbc237493367 | grep -P'((内存)|(Pid))'

"Pid": 16283,
"PidMode": "",
"Memory": 10737418240,
"KernelMemory": 0,
"MemoryReservation": 0,
"MemorySwap": -1,
"MemorySwappiness": -1,
"PidsLimit": 0,

ps auxw | grep 16283

/usr/lib/jvm/java-8-openjdk-amd64/bin/java -Xms9000m -Xmx9000m -XX:MaxPermSize=1024m -XX:ReservedCodeCacheSize=512m ...

cat /proc/16283/status | grep -i vm

VmPeak: 20807456 kB
VmSize: 19735624 kB
VmLck:         0 kB
VmPin:         0 kB
VmHWM:   6967836 kB
VmRSS:   3356220 kB
VmData: 19661552 kB
VmStk:       140 kB
VmExe:         4 kB
VmLib:     17964 kB
VmPTE:     24956 kB
VmPMD:        92 kB
VmSwap:  6283192 kB

docker --version

Docker version 1.12.2, build bb80604

因此:
1)docker 容器最大内存设置为 10gb
2)java 应用程序最大内存设置为 9gb
3)VmSwap 值为 6gb...

问题:
这怎么可能?为什么要使用交换内存?

答案1

Linux 内核有一个名为 的值swappiness,它告诉内核在开始使用交换之前要使用多少内存。默认情况下,它通常约为 60%,因此它不会等到使用完所有内存后才将内容放入交换中。这可能是一个好主意;将交换内容放入交换需要时间。内核会在可能的情况下留出额外的内存以节省时间。

关于为什么会这样,还有更多信息这个问题

编辑:知道 -1 交换性来自哪里吗?我很好奇,我以前从未见过。你试过将其设置为 0 吗?

答案2

感谢人们在这里写的提示。

因此,我做了两件事:
1)增加容器内存,因为 -Xmx 不包括线程所需的内存(线程数 * 堆栈大小),并且我的应用程序使用了数千个线程
2)将“docker run”内存选项从“--memory 10G”更改为“--memory 10G --memory-swap=10G --memory-swappiness=0”

因此,现在我希望不再使用交换。

相关内容