有一个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”
因此,现在我希望不再使用交换。