memory - Docker 的 --memory 开关无法按预期工作

标签 memory memory-management docker

序言

我正在写一个小演示文稿来列出使用 Docker 时的一些“陷阱”,我也遇到了自己的一个问题。

在解释让 Docker 在没有内存限制的情况下运行的危险时,我发现它的行为不像我预期的那样。

我使用 PHP 脚本创建了一个 docker 镜像,该脚本将递归地创建数组以耗尽内存,报告当前使用了多少内存。如果没有设置内存限制,脚本会在 1gb 处自行终止。

您可以在这里获取图片:https://hub.docker.com/r/gisleburt/my-memory-hog
您可以在此处查看源代码:https://github.com/Gisleburt/my-memory-hog

我的期望是以下内容会阻止脚本超过 128mb 的内存。

docker run -it --memory=128m --memory-swap=0 gisleburt/my-memory-hog

然而,在 OSX(本地和使用虚拟盒驱动程序的 docker-machine)上,docker 实际上是 250mb 之前的脚本。在 Ubuntu 上,脚本达到 1gb 并杀死自己。

更奇怪的是,如果我们检查 docker stats 发生了什么,我们可以看到容器实际上并没有超过它的内存限制。实际上,使用 --memory=4m 运行在 Ubuntu 上,docker stats仍然说它不使用超过 4mb,即使脚本以 1gb 完成。在 Mac 上,限制为 4mb 会杀死 5-6mb 左右的脚本。

我想我错过了关于内存分配方式的一些东西,但我无法弄清楚它是什么。

问题

为什么 docker 容器中的脚本似乎比 docker 容器使用更多内存?容器内外的内存发生了什么?

版本信息

Mac 客户端:
Client:
 Version:      1.12.3
 API version:  1.24
 Go version:   go1.6.3
 Git commit:   6b644ec
 Built:        Thu Oct 27 00:09:21 2016
 OS/Arch:      darwin/amd64
 Experimental: true

Mac 原生:
Server:
 Version:      1.12.3
 API version:  1.24
 Go version:   go1.6.3
 Git commit:   6b644ec
 Built:        Wed Oct 26 23:26:11 2016
 OS/Arch:      linux/amd64

Mac 虚拟机:
Server:
 Version:      1.12.3
 API version:  1.24
 Go version:   go1.6.3
 Git commit:   6b644ec
 Built:        Thu Oct 27 00:09:21 2016
 OS/Arch:      linux/amd64
 Experimental: true

Ubuntu客户端:
Client:
 Version:      1.12.3
 API version:  1.24
 Go version:   go1.6.3
 Git commit:   6b644ec
 Built:        Wed Oct 26 22:01:48 2016
 OS/Arch:      linux/amd64

Ubuntu引擎:
Server:
 Version:      1.12.3
 API version:  1.24
 Go version:   go1.6.3
 Git commit:   6b644ec
 Built:        Wed Oct 26 22:01:48 2016
 OS/Arch:      linux/amd64

最佳答案

在我们技术部门的一些人,特别是我们平台运营团队的一名成员的帮助下,我们弄清楚了发生了什么,并在 reference guide 中有所提及。 .

--memory-swap Total memory limit (memory + swap, format: <number>[<unit>]). Number is a positive integer. Unit can be one of b, k, m, or g.



说白了,--memory-swap是可用的内存总量,包括常驻内存和交换内存。

为了获得预期的效果,您必须运行:
docker run -it --memory=128m --memory-swap=128m gisleburt/my-memory-hog

在此示例中 memory = 128mb , 和 memory + swap = 128mb因此swap = 0 .

不能为 --memory-swap 指定数字也是有道理的。大于 0,但小于 --memory .

此外,虽然 --memory-swap=-1通过交换为您提供“无限”的内存量,出于某种原因,设置 --memory-swap=0似乎使内存和交换 同尺寸 ,为您提供两倍于预期的内存总量。

您也可以使用 --memory-swappiness=0 关闭交换。 .尽管可能会创建交换文件,但它不会被写入,因此不会占用比空文件更多的磁盘空间。

TL;DR:
--memory = RES
--memory-swap = VIRT = RES + SWAP

关于memory - Docker 的 --memory 开关无法按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40485302/

相关文章:

java内存大小优化

memory - 为什么 OCaml 需要创建自己的堆来进行垃圾回收?

c - 从 K&R 书中解释 malloc 的这种实现

python-3.x - Python 占用的内存是应有的六倍

C++ new 运算符——内存布局

c - 如何在基于 Linux 的嵌入式设备上造成内存碎片?

c - 正在释放的指针未分配给 C 中的字符串数组

ubuntu - 安装 docker-machine 和/或 docker-compose 的 Curl 命令在 Ubuntu Xenial 中不起作用

node.js - 我可以使用 MongoDb 驱动程序从 node.js 调用 rs.initiate() 和 rs.Add() 吗?

postgresql - 如何配置 PostgreSQL ODBC 驱动程序