16_内存相关
约 1075 字大约 4 分钟
2026-07-14
一、查看物理内存条(硬件层)
- dmidecode(最详细,首选)
完整信息
sudo dmidecode -t memory
只看内存条(type 17 = Memory Device)
sudo dmidecode -t 17
Handle 0x1100, DMI type 17, ...
Memory Device
Array Handle: 0x1000
Total Width: 72 bits ← ECC 内存(72=64+8 ECC);非 ECC 是 64
Data Width: 64 bits
Size: 32 GB ← 这根条子的容量
Form Factor: DIMM ← 服务器一般 DIMM;笔记本 SODIMM
Locator: DIMM_A1 ← 插在哪个槽(板子丝印名)
Bank Locator: NODE 1 ← 在哪个 CPU/NUMA 域
Type: DDR4 ← DDR3/DDR4/DDR5
Type Detail: Synchronous Registered (Buffered) ← RDIMM (服务器常见)
Speed: 2933 MT/s ← 这根条子支持的最高速率
Manufacturer: Samsung
Serial Number: 12345678
Asset Tag: ...
Part Number: M393A4K40CB2-CVF ← 厂商型号
Rank: 2 ← Single-rank / Dual-rank
Configured Memory Speed: 2666 MT/s ← 实际跑的速率(受 CPU/主板限制)
Minimum Voltage: 1.2 V
Maximum Voltage: 1.2 V
Configured Voltage: 1.2 V只看内存阵列概况(type 16)
sudo dmidecode -t 16
OOM的机制
Linux 的 OOM Killer(Out Of Memory Killer) 是靠“算分”来决定杀谁的。在内核中,这套逻辑主要依赖两个核心分数值:oom_score_adj(人工干预分)和 oom_score(内核计算的最终淘汰分)。
对于系统里的每一个进程(以 PID 为 1234 为例),在 /proc/1234/ 目录下都有三个与之相关的文件:
- /proc/1234/oom_score_adj(可读写): 允许系统管理员或容器运行时(如 Docker)手动调整该进程被杀的优先级; 取值范围是[-1000, 1000], -1000绝对不会被OOM 机制 kill;
- /proc/1234/oom_score(只读): 显示内核当前为该进程计算出来的 最终 OOM 杀除得分; 取值范围: [0, 1000]。分数越高,越容易被杀。
- /proc/1234/oom_adj: 这个是老版的配置项了,为了向后兼容还存在,可用忽略
当爆内存的时候,内核会调用函数来遍历系统中的所有进程进行打分:
$$\text{最终分数 } (oom\_score) = \text{进程内存占用占比(千分比)} + \text{人工调整值 } (oom\_score\_adj)$$总之分越高,死的越快!
Swap
Swap 就是常说的虚拟内存,在正常情况下服务器运行程序全靠 内存, 但内存被占满的时候,就会触发 OOM-killer 机制,按照内核的 Killer 算法,对全部运行的进程打分,然后Kill掉分最低的。
在有Swap的情况下,Linux内核会将内存中哪些 最不活跃的数据(最少被CPU调用的数据页), 从内存换到 /swapfile 硬盘空间里面,空出来的内存就可以匀给紧急的程序用。
什么时候不推荐(甚至严禁)开 Swap?
很多人会听说“服务器要关闭 Swap 性能才最好”,这也没错,以下场景通常会主动关闭它:
1.Kubernetes (K8s) 容器集群节点
K8s 官方在很长一段时间里都强制要求关闭 Swap。因为 K8s 的核心理念是“精确调度”。它需要明确知道每个节点还有多少准确的物理内存。如果开了 Swap,会导致调度器对资源的预估失准。
2.极致追求低延迟、高并发的纯内存数据库
Redis、ClickHouse、Elasticsearch。这类业务对响应时间是微秒级的。如果开了 Swap,内核一旦把核心数据交换到了“相对极慢”的磁盘上,当程序去读这个数据时,就会发生严重的卡顿(Page Fault / 页缺失),导致整个高并发服务雪崩。
3.高频核心计算/HPC/量化交易
宁愿让它因为内存不足直接报错、让人工介入,也绝不能接受程序在硬盘置换中慢吞吞地运行。
配置Swap的流程
# 以创建一个 16GiB 的 Swap 文件为例
# 1. 在根目录下创建一个 16GiB 的全零空文件
dd if=/dev/zero of=/swapfile bs=1M count=16384
# 2. 赋予安全权限:仅允许 root 用户读写(权限不对内核会拒绝启用)
chmod 600 /swapfile
# 3. 将该文件格式化为交换分区(Swap)格式
mkswap /swapfile
# 4. 立刻激活并启用该 Swap 文件
swapon /swapfile
# 5. 验证 Swap 是否生效
free -h
# 6. 设置永久生效(可选)
默认的 swapon 只是临时生效,机器重启后会失效。需要将其写入系统挂载配置文件中
echo '/swapfile none swap sw 0 0' >> /etc/fstab