Внутри находится докер-контейнер с java-приложением.
докер осмотреть 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) максимальная память контейнера докеров установлена на 10 ГБ
2) максимальная память Java-приложения установлена на 9 ГБ
3) Значение VmSwap составляет 6 ГБ ...
Вопрос:
как такое возможно? Почему используется память подкачки?
Спасибо за советы, написанные здесь.
Итак, я сделал 2 вещи:
1) причина увеличения памяти контейнера -Xmx не включает память, необходимую для потоков (количество потоков * размер стека), а мое приложение использует тысячи потоков
2) изменены параметры памяти "docker run" с "--memory 10G" на "--memory 10G --memory-swap = 10G --memory-swappiness = 0"
Итак, теперь я ожидаю, что своп больше не будет использоваться.
Ядро Linux имеет значение, называемое swappiness
, который сообщает ему, какой объем памяти использовать, прежде чем он начнет использовать подкачку. По умолчанию это обычно где-то около 60%, поэтому вам не нужно ждать, чтобы использовать всю вашу память, прежде чем помещать данные в своп. Наверное, это хорошая идея; требуется время, чтобы поменять местами коммутаторы. Ядро оставляет дополнительную память, когда это возможно, чтобы сэкономить время.
Больше информации о том, почему это так, можно найти в этот вопрос
РЕДАКТИРОВАТЬ: Есть идеи, откуда взялась подкачка -1? Мне любопытно, я такого раньше не видел. Вы пробовали установить его на 0?