首页 > 系统相关 >容器内存相关知识

容器内存相关知识

时间:2022-11-13 23:36:24浏览次数:66  
标签:容器 查看 知识 内存 memory 进程 docker

这篇文章是我研究容器内存整理出的相关内容. 前后内容并没有上下文关系, 每个知识点都可以单独查看.

内存控制

使用这样的命令启动一个容器docker run -d -m 300M xxx. 可以限制容器使用的内存最大为300M. 那么docker是如何实现容器的内存限制呢?

其实是操作系统已经做好了支持. Linux中实现容器的两大技术是:

  • namespace: 使用不同的命名空间实现资源的隔离. 包括:
    • PID: 进程隔离
    • Net: 网络环境隔离
    • VFS: 文件系统隔离
    • IPC: 进程通信隔离
    • 等等, 可查看维基百科
  • cgroups: 实现对进程资源的限制. 包括: cpu/内存/最大进程数量等等. 详情可查看官方文档

好, namespace实现了多个容器间不同进程的隔离, cgroups实现了对单个容器的资源限制. 就是这两个技术支撑了容器化的实现.

要查看一个进程的cgroups限制, 可查看文件/proc/<pid>/cgroup. 如果是一个容器进程, 你会看到类似于这样的内容:

...
10:memory:/docker/<docker_id>
9:cpuset:/docker/<docker_id>
8:blkio:/docker/<docker_id>
...

将限制指向了一个路径, 这个路径存放在/sys/fs/cgroup这里, 比如memory的限制路径为: /sys/fs/cgroup/memory/docker/<docker_id>. 在这里能够看到对此进程的所有内存限制. 其中每个文件的含义在官方文档中也有说明.

至于具体的原理, 这里不做深究.

这里额外说一点, /sys/fs/cgroup是一个树形结构, 子控制组的资源限制必定小于等于父控制组.

OOM Kill

如果一个进程的内存使用超过了限制, 会发生什么呢?

随便写一个脚本实验一下, 就会发现进程突然消失了, 被操作系统杀掉了.

使用docker inspect命令查看, 发现OOMKilled的值为true. 或者直接查看系统日志/sys/log/message也能够看到进程被杀掉的log.

Page Cache

我们可能会碰到这样奇怪的现象, 容器的内存限制为200M, 且已经使用200M内存, 此时再启动一个进程申请20M内存仍然成功, 且申请后总的内存仍然是200M.

造成这个奇怪现象的原因, 是因为在调用函数read读取文件的时候, 会将文件临时存放在内存中, 以加速后续读取. 我们使用free命令查看时, 其中的buff/cache就是文件的缓存, RSS则是实际使用的物理内存, VIRT则是进程申请的虚拟内存. 某个进程的具体内存分布可查看文件proc/<pid>/smaps.

容器RSSbuff/cache的和, 就是容器实际使用的物理内存总值. 应该与cgroup路径下的memory.usage_in_bytes值相同. (容器的内存分布也可以查看文件memory.stat)

这么一说, 这个奇怪的现象是不是就可以解释了? 当内存不足的时候, 系统会回收文件缓存以供进程使用.

交换内存

如果容器开启了交换内存, 你就会惊奇的发现, memory cgroup限制失效了. 容器申请了超过限制的内存仍然可以继续执行, 只不过部分内存被交换到磁盘上了.

如果同时又Page Cache和交换内存, 操作系统优先选择哪一个呢? 可以通过修改memory.swappiness的值来修改优先级, 其值为0-100, 值越大, 使用交换内存的概率越大. 当值为100时, 则Page Cache与叫换内存的概率相同. 官网介绍

不过一般启动容器的时候, 都是将swap关闭的, 应该没什么需要开启的场景吧.


还有一些内存相关的其他知识点, 大部分都可查看memory group官方文档

原文地址: https://hujingnb.com/archives/865

标签:容器,查看,知识,内存,memory,进程,docker
From: https://www.cnblogs.com/hujingnb/p/16887676.html

相关文章

  • 宋宝华:Linux内核中用GFP_ATOMIC申请内存究竟意味着什么?
    本文目的本文补充校正一些Linux内核开发者关于GFP_ATOMIC的认知不完整的地方,阐述GFP_ATOMIC与free内存watermark的关系,并明确什么时候应该用GFP_ATOMIC申请内存。目录:G......
  • 基于微信小程序的知识题库系统设计与实现-计算机毕业设计源码+LW文档
    小程序开发说明开发语言:Java框架:ssmJDK版本:JDK1.8服务器:tomcat7数据库:mysql5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:Maven3.3.9......
  • C语言数组越界和内存分配
    事情经过11月3日晚,今天遇到了一个神奇的现象,一个大小为10的数组可以容纳200个数据,直接震惊我了!今天发11月2日的参考代码,有一个同学给我看他的代码,大概是这样的intmain(......
  • JSON基础知识
    JSON是一种轻量级的数据交换格式。JSON格式:key:value键值对。JSON的值可以是数字、字符串、BOOL、数组、对象。JSON的优点:数据体积小程序猿编写容易相对XML,JSON不......
  • 【博学谷学习记录】超强总结,用心分享 。java基础知识。
    Java基础知识1.面向对象的特征封装:就是把对象的属性和行为结合为一个独立的整体,并尽可能隐藏对象的内部实现细节,就是把不想告诉或者不该告诉别人的东西......
  • Docker Alpine 容器修改/etc/hosts 不生效的问题
     DockerAlpine容器修改/etc/hosts不生效的问题有些团队开的工作开发时喜欢使用修改hosts来绑定开发域名和子域名之间的cookie共享,但是在使用golangapp使用alpine......
  • 现代操作系统(第3章 内存管理)
    目录3.1无存储器抽象3.2一种存储器抽象:地址空间3.2.1地址空间的概念基址寄存器与界限寄存器3.2.2交换技术3.2.3空闲内存管理1.使用位图的存储管理2.使用链表的存储管......
  • 1.举例说明常用的7中数据寻址方式和3中内存地址的寻址方式, 2.总结16、32和64位CPU的
    数据寻址方式:(1)立即寻址,MOVAX,1234H(2)寄存器寻址,寄存器寻址的特点是操作数在CPU内部的寄存器中,在指令中指定寄存器号(3)直接寻址,MOVES:[5678H],BL(4)寄存器间接寻址,MOV[......
  • 互联网基础知识
    网络协议网络协议是一种网络通讯语言,为连接不同操作系统和不同硬件体系结构的互联网提供通信支持。开发者一般使用最上层应用层的协议来进行网络数据传输,数据会从上层协......
  • 盛水最多的容器,局部最优解
      import java.util.*;public class Solution {    /**     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可    ......