# 【Linux】swap相關

[![image-1766024226901.png](https://bookstack.treemanou.com/uploads/images/gallery/2025-12/scaled-1680-/yTgfr35JUr1Zp9If-image-1766024226901.png)](https://bookstack.treemanou.com/uploads/images/gallery/2025-12/yTgfr35JUr1Zp9If-image-1766024226901.png)

從你貼的 `top` 看起來 **Swap 使用率偏高**（`KiB Swap: 79.8/1044476` 很像是 79.8% / 1,044,476 KiB），要「釋放 swap」本質上就是**把已經換到 swap 的頁面搬回 RAM**。最直接的方法是 **swapoff → swapon**（會短暫吃 RAM、可能卡頓一下）。

## ✅ 1) 先確認 RAM 夠不夠（很重要）

```bash
free -h
swapon --show

```

看 `available`（可用記憶體）要 **大於目前 swap 已用量**（最好再多留一些 buffer），不然 `swapoff` 可能 OOM 或把機器拖很慢。

```
[root@localhost ~]# free -h 
total used free shared buff/cache available 
Mem: 45G 25G 1.8G 226M 18G 20G 
Swap: 1.0G 814M 205M 

[root@localhost ~]# swapon --show 
NAME TYPE SIZE USED PRIO 
/dev/dm-1 partition 1020M 814.2M -2
```

## ✅ 2) 一次清空 swap（常用）

```bash
sudo swapoff -a
sudo swapon -a

```

清完再確認：

```bash
free -h
swapon --show

```

> 若你是 swapfile（例如 `/swap.img` 或 `/swapfile`），也可只針對單一檔案：

```bash
sudo swapoff /swap.img   # 或 /swapfile
sudo swapon  /swap.img

```

## ✅ 3) 找出「誰在吃 swap」（不然很快又會回來）

### 有 smem 最方便

```bash
sudo apt-get update && sudo apt-get install -y smem
sudo smem -rs swap | head

```

### 沒有 smem：用 /proc 快速抓（由大到小）

```bash
# who_use_swap.sh
#!/bin/bash
for p in /proc/[0-9]*; do
  pid=${p##*/}
  swap=$(awk '/VmSwap:/ {print $2}' $p/status 2>/dev/null)
  comm=$(tr -d '\0' < $p/comm 2>/dev/null)
  if [ -n "$swap" ] && [ "$swap" -gt 0 ]; then
    printf "%10s KiB  pid=%s  %s\n" "$swap" "$pid" "$comm"
  fi
done | sort -nr | head -20

```

⚠️ 小提醒：`swapoff` 期間會把資料搬回 RAM，可能造成短暫卡頓/IO 增加；如果是線上服務，建議離峰做，或先找出吃 swap 的程序再處理。

---

### ✅ swapoff 如何觀察？

用 `watch` 最方便：

```bash
watch -n 5 free -h

```

想加上時間戳一起看：

```bash
watch -n 5 'date; echo; free -h'

```

離開按 `q`（或 `Ctrl+C`）。

```
Every 5.0s: date; echo; free -h                                                                    
Thu Dec 18 10:23:47 2025

Thu Dec 18 10:23:47 CST 2025

              total        used        free	 shared  buff/cache   available
Mem:            45G         25G        994M        230M         18G         19G
Swap:          1.0G          0B        1.0G
```

---

### ✅ 什麼情況才需要「清快取」？

以下有需要放快取，獲得記憶體空間嗎

```
Every 5.0s: date; echo; free -h                                                                    
Thu Dec 18 10:23:47 2025

Thu Dec 18 10:23:47 CST 2025

              total        used        free	 shared  buff/cache   available
Mem:            45G         25G        994M        230M         18G         19G
Swap:          1.0G          0B        1.0G
```

你現在重點要看的是：

- `available = 19G`：代表系統評估「真的能拿來給程式用」的記憶體還有 19G（包含可回收的 cache）。這個數字大 → **不缺記憶體**。
- `buff/cache = 18G`：這是 Linux 用來加速 I/O 的檔案快取，**需要時會自動回收**，不是浪費。
- `free = 1.5G` 很低是正常現象，Linux 會盡量把閒置 RAM 拿去當 cache。

所以：**沒有必要清 cache**，清了反而會讓磁碟/檔案讀取變慢（cache 被你清掉了）。

---

### ✅ 如何判斷「到底有沒有影響」：

```bash
vmstat 1

```

看 `si` / `so`（swap in / swap out）：

- 長時間都是 0 → swap 雖然滿，但**幾乎沒在動**，影響很小
- 一直有數字跳 → 有在頻繁換頁，**延遲抖動**就會比較明顯，建議處理或找出吃 swap 的程序

```
[root@localhost ~]# vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 2  0 354480 1360744    788 19839980    0    0     0    16    0    0  2  1 97  0  0
 1  0 354040 1360720    788 19840012  440    0   440   778 10902 12281  2  7 91  0  0
 2  0 353108 1357988    788 19840088  932    0   932    83 14391 17944  5  8 87  0  0
 2  0 352616 1355888    788 19840140  460    0   460   117 15671 19400  7  8 85  0  0
 3  0 351912 1357268    788 19840132  640    0   640   142 15713 19048  5  8 87  0  0
 2  0 351448 1355556    788 19840140  436    0   436    92 13794 15914  2  8 90  0  0
 2  0 350628 1357180    788 19840156  720    0   720   174 18513 21545  4  9 87  0  0
 1  0 349144 1355736    788 19840136 1484    0  1484    77 11470 13126  2  7 91  0  0
 2  0 348476 1354372    788 19840136  668    0   668    79 11530 12891  2  7 91  0  0
^C
```

你這段 `vmstat 1` **顯示「swap 正在被讀回 RAM」**，而且是連續的：

- `si`（swap in）一直有 **440 / 932 / 1484 … KB/s**
- `so`（swap out）是 0
- `swpd` 也在 **一路下降**（354480 → 348476 …）

這代表：**有程式正在碰到曾經被換到 swap 的記憶體頁面**，系統就把它從 swap 讀回來；目前沒有再把新的頁面換出去。

### 會有什麼影響？

1. **尾延遲抖動（最典型）**  
    只要 `si` 不為 0，就表示有 swap I/O；那段時間碰到這些頁面的 thread 可能會卡一下（但你 `wa=0` 表示目前 I/O 沒被堵住，所以感受可能不明顯或很輕微）。
2. **swap 滿會降低緩衝空間**  
    現在 `so=0` 代表還沒再把東西換出去；但如果之後遇到瞬間記憶體壓力，swap 已滿會讓系統更容易走向 OOM / 更劇烈 reclaim。

---

## ✅ swap 不清會有什麼影響

不清 swap 通常**不會有立即性壞處**，但會有幾個「可能的影響」，看你的工作型態而定：

### 1) 效能：偶爾的延遲抖動（最常見）

swap 裡的資料如果之後又被用到，就會發生 **page-in**（從磁碟/SSD 讀回 RAM），比 RAM 慢很多，所以可能出現：

- API / job 偶發性變慢、尾延遲（p95/p99）變差
- 某個服務「突然卡一下」

你現在 swap 只有 520MB，通常影響不大；但若剛好那 520MB 裡面是常被碰到的頁面，就會感覺得到。

### 2) 反映「過去曾經記憶體吃緊」

swap 被用滿常代表之前某個時段 RAM 壓力大（尖峰、記憶體洩漏、或短時間大量 cache / buffer / workload）。

- **不清 swap** 不代表現在還缺 RAM（你 `available` 很大就不缺）
- 但它是一個訊號：建議你偶爾追一下「誰在用 swap」避免問題重演

### 3) swap 滿了之後的風險：下次再吃緊會更容易出事

swap 如果已經 100%：

- 下次記憶體再緊，系統沒有 swap 空間可用，可能更快走向 **OOM kill**
- 或者進入更劇烈的 reclaim/抖動（視你的 kernel/設定）

### 4) 不清 swap 本身不會「佔著 RAM」

很多人誤會：swap 滿了會把 RAM 壓縮。其實 swap 佔的是磁碟區塊，不會直接吃掉你的 RAM。  
你真正該看的仍是 `available`、以及是否有頻繁 swap in/out。

---

### ✅ 説明 /dev/dm-1 意義 ， 與 -a 哪裡不同  
sudo swapoff /dev/dm-1   
sudo swapon /dev/dm-1

好，先用你現在看到的資訊來對照講：

## `/dev/dm-1` 是什麼意思？

- `dm` = **device-mapper**（Linux 的「裝置映射」層）
- `/dev/dm-1` 代表「第 2 個 device-mapper 裝置」（編號從 0 開始），通常是：
    
    
    - **LVM logical volume**（最常見，例如 `centos-swap`）
    - 或 dm-crypt / multipath 這類透過 device-mapper 建出來的裝置
- 因為你 `swapon --show` 顯示它是 `TYPE partition`，表示它是一個「區塊裝置/分割區型態」拿來當 swap。

想看它真正對應到什麼名字（建議你查一下）：

```bash
ls -l /dev/dm-1
lsblk -f
sudo dmsetup info -C
sudo dmsetup ls --tree

```

通常你會看到像 `centos-swap` 或 `vgname-swap` 之類的 LV 名稱。

---

## `-a` 跟指定 `/dev/dm-1` 有什麼不同？

### 1) 作用範圍不同

- `swapoff /dev/dm-1`：**只針對這一個 swap**
- `swapoff -a`：**針對所有已啟用的 swap**（全部停用）
- `swapon -a`：把 `/etc/fstab` 裡標記為 swap 的項目 **全部啟用回來**

### 2) 安全性/可控性不同

- 如果你機器上只有一個 swap（你現在看起來是），兩者結果幾乎一樣。
- 如果你有多個 swap（例如：一個 swap 分割區 + 一個 swapfile），用 `-a` 會一次動到全部；指定裝置比較可控，避免不小心把你不想動的 swap 也關掉。

### 3) `-a` 依賴 `/etc/fstab`

- `swapon -a` 會依照 `/etc/fstab` 去開啟 swap
- 若某個 swap 沒寫在 fstab、或用系統/雲平台動態掛的，`-a` 可能不會把它開回來；指定 `/dev/dm-1` 就不受這個影響。

---

## 你這台怎麼選？

你現在 `swapon --show` 只有一個 `/dev/dm-1`，所以：

- 想精準可控：用你貼的這兩行 ✅
- 想一鍵通用：`swapoff -a; swapon -a` 也可以 ✅

---

## ✅ 降低未來再大量使用 swap（可選）

```bash
sudo sysctl -w vm.swappiness=10

```

要永久生效：

```bash
echo 'vm.swappiness=10' | sudo tee /etc/sysctl.d/99-swappiness.conf
sudo sysctl --system

```

`sudo sysctl -w vm.swappiness=10` 這行是在 **「立即」調整 Linux kernel 對 swap 的使用傾向**。

---

- `sysctl`：用來讀/寫 Linux kernel 的即時參數（位於 `/proc/sys/`）
- `-w`：write（寫入）
- `vm.swappiness`：控制 **「多願意把記憶體頁面換到 swap」** 的參數
- `=10`：把 swappiness 設成 10（偏向少用 swap）

等價於：

```bash
echo 10 | sudo tee /proc/sys/vm/swappiness

```

---

#### vm.swappiness 代表什麼？

#### 範圍（常見）

- 通常是 **0 ~ 100**
- 數字越大 → kernel 越積極把「較少用到的記憶體頁面」換到 swap（更早換、更常換）
- 數字越小 → kernel 越傾向把資料留在 RAM、寧可回收 page cache，也比較不主動換到 swap

> 很多人會用 10 或 1 來降低 swap 對延遲的影響（尤其是 DB、API、線上服務）。

---

##### 調成 10 的「實際效果」

- **更晚才開始 swap out**（把 RAM 的匿名頁面換到 swap）
- 會更偏向：
    
    
    - 先回收 / 讓出 filesystem cache（`buff/cache`）
    - 盡量把程式的工作集留在 RAM
- 通常可降低：
    
    
    - 尾延遲抖動（p95/p99）
    - swap I/O 造成的卡頓

---

##### 常見誤解：swappiness=10 會把現有 swap 清掉嗎？

不會。

- `swappiness` 只影響「未來是否要換出去」的策略
- 你現在已經在 swap 裡的頁面，不會因為改成 10 就自動搬回 RAM  
    要清掉還是要靠：

```bash
swapoff -a && swapon -a

```

---

#### 風險 / 代價是什麼？

- 如果 swappiness 設太低（例如 0 或 1），在記憶體壓力來時：
    
    
    - kernel 會更晚使用 swap
    - 可能更快觸發 **OOM kill**（把某些程序殺掉）來保護系統
- 所以對「希望系統穩住不要 OOM」的場景，有時會保留比較高的值（例如 20~60），讓 swap 當緩衝。

> 你的機器 RAM 45G、swap 很小（520M~1G），把 swappiness 降到 10 通常是合理的偏好：少 swap、降低抖動。

---

##### 這設定會持久嗎？

不會。重開機會還原。

要永久化：

```bash
echo 'vm.swappiness=10' | sudo tee /etc/sysctl.d/99-swappiness.conf
sudo sysctl --system

```

---

##### 建議你怎麼驗證有沒有幫助？

改完後觀察：

```bash
vmstat 1

```

看 `so`（swap out）是否長期維持 0，系統是否少出現延遲抖動。

如果你願意貼 `cat /proc/sys/vm/swappiness` 以及你的服務類型（DB / API / ELK / Docker host），我可以給你更適合的 swappiness 建議值。