Linux swap交换分区的创建与调整方案

 更新时间:2026年04月17日 09:20:19   作者:Jinkxs  
文章详细介绍了Linux系统Swap的工作原理、创建方法、动态调整技巧,并结合Java应用场景提供了实用的代码示例和性能优化建议,重点强调合理配置Swap对系统稳定性和性能的重要性,以及在不同环境下的最佳实践,需要的朋友可以参考下

在现代 Linux 系统管理中,Swap(交换空间)是一个虽然“古老”却依然至关重要的概念。即使在内存价格低廉、服务器动辄配备数十甚至上百 GB 内存的今天,合理配置和管理 Swap 仍然是保障系统稳定性和性能的关键环节。本文将带你深入理解 Linux Swap 的工作原理、创建方法、动态调整技巧,并结合 Java 应用场景,提供实用的代码示例和性能优化建议。

什么是 Swap?

Swap 是 Linux 系统中用于扩展物理内存的一种机制。当系统的物理内存(RAM)不足时,内核会将一部分暂时不用的内存页(pages)写入到磁盘上的 Swap 区域,从而腾出物理内存供活跃进程使用。这个过程称为“换出”(swap out);当这些数据再次被访问时,系统又会将其从磁盘读回内存,称为“换入”(swap in)。

注意:Swap 并非 RAM 的替代品,而是其补充。频繁的 Swap 操作会导致严重的性能下降,因为磁盘 I/O 速度远低于内存访问速度。

Swap 可以是:

  • 一个专用的磁盘分区(传统方式)
  • 一个普通文件(现代常用方式)
  • 多个 Swap 分区或文件组成的集合

Swap 工作原理图解

上图展示了 Swap 在内存压力下的基本工作流程。内核通过页面置换算法(如 LRU)选择哪些页面应该被换出,以最小化对系统性能的影响。

查看当前 Swap 状态

在进行任何操作之前,首先需要了解当前系统的 Swap 配置情况。Linux 提供了多种命令行工具来查看 Swap 使用状态。

使用free命令

free -h

输出示例:

              total        used        free      shared  buff/cache   available
Mem:           7.7G        2.1G        3.2G        245M        2.4G        5.1G
Swap:          2.0G        0B          2.0G

这里的 -h 参数表示“human-readable”,即以人类可读的方式显示大小(如 G、M)。

使用swapon命令

swapon --show

输出示例:

NAME      TYPE SIZE USED PRIO
/dev/sda5 partition 2G   0B   -2

该命令列出所有激活的 Swap 设备及其类型、大小、已使用量和优先级。

查看/proc/swaps

cat /proc/swaps

这是内核维护的 Swap 信息文件,内容与 swapon --show 类似。

创建 Swap 文件(推荐方式)

相比传统的 Swap 分区,使用文件作为 Swap 更加灵活,特别是在云服务器或虚拟机环境中,无需重新分区即可动态调整大小。

步骤一:创建空文件

使用 fallocatedd 创建指定大小的文件。

方法 1:使用fallocate(快速)

sudo fallocate -l 2G /swapfile

✅ 优点:瞬间完成,不实际写入磁盘数据。
❌ 缺点:某些文件系统(如 ext3)或旧版本内核可能不支持。

方法 2:使用dd(兼容性好)

sudo dd if=/dev/zero of=/swapfile bs=1M count=2048

解释:

  • if=/dev/zero:输入文件为零设备
  • of=/swapfile:输出文件路径
  • bs=1M:块大小为 1MB
  • count=2048:复制 2048 个块,总计 2GB

此方法较慢,因为它会实际写入零值填充整个文件。

步骤二:设置权限

出于安全考虑,Swap 文件应仅对 root 可读写:

sudo chmod 600 /swapfile

步骤三:格式化为 Swap

sudo mkswap /swapfile

输出示例:

Setting up swapspace version 1, size = 2 GiB (2147479552 bytes)
no label, UUID=abcd1234-ef56-7890-abcd-ef1234567890

步骤四:启用 Swap

sudo swapon /swapfile

立即生效,无需重启。

步骤五:设置开机自动挂载

编辑 /etc/fstab 文件,在末尾添加一行:

/swapfile none swap sw 0 0

保存后,系统将在每次启动时自动启用该 Swap 文件。

调整现有 Swap 大小

有时我们需要扩大或缩小现有的 Swap 空间。以下是安全调整 Swap 文件大小的步骤。

扩大 Swap 文件

假设我们要将 /swapfile 从 2GB 扩展到 4GB:

# 1. 关闭当前 Swap
sudo swapoff /swapfile

# 2. 删除旧文件
sudo rm /swapfile

# 3. 创建新的更大文件
sudo fallocate -l 4G /swapfile

# 4. 设置权限
sudo chmod 600 /swapfile

# 5. 格式化
sudo mkswap /swapfile

# 6. 重新启用
sudo swapon /swapfile

# 7. 验证
free -h

小贴士:如果你不想删除原文件,也可以直接使用 truncate 命令扩容:

sudo truncate -s 4G /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

缩小 Swap 文件

缩小 Swap 文件风险较高,必须确保缩小后的空间仍能满足当前内存需求。

# 1. 关闭 Swap
sudo swapoff /swapfile

# 2. 重建较小的文件(例如 1GB)
sudo dd if=/dev/zero of=/swapfile bs=1M count=1024

# 3. 设置权限
sudo chmod 600 /swapfile

# 4. 格式化
sudo mkswap /swapfile

# 5. 启用
sudo swapon /swapfile

警告:缩小 Swap 文件前,请确保系统有足够的物理内存,否则可能导致 OOM(Out of Memory)错误。

Swap 优先级与多个 Swap 设备

Linux 支持同时使用多个 Swap 设备(分区或文件),并通过优先级(priority)决定使用顺序。优先级数值越大,越先被使用。

查看优先级

swapon --show

输出可能如下:

NAME         TYPE      SIZE USED PRIO
/swapfile1   file      2G   0B   -2
/swapfile2   file      1G   0B   -1

这里 /swapfile2 优先级更高(-1 > -2),会被优先使用。

设置优先级

在启用 Swap 时指定优先级:

sudo swapon -p 10 /swapfile

或者在 /etc/fstab 中设置:

/swapfile none swap sw,pri=10 0 0

实战建议:将高速 SSD 上的 Swap 文件设置为高优先级,低速 HDD 上的设置为低优先级,可提升整体性能。

动态管理 Swap:启用与禁用

在运维过程中,有时需要临时关闭或开启某个 Swap 设备。

禁用单个 Swap

sudo swapoff /swapfile

禁用所有 Swap

sudo swapoff -a

警告:在物理内存不足的情况下禁用所有 Swap 可能导致系统崩溃或进程被 OOM Killer 杀死。

启用所有在 fstab 中定义的 Swap

sudo swapon -a

这通常在系统启动时由 init 系统自动执行。

监控 Swap 使用情况

持续监控 Swap 使用有助于及时发现内存瓶颈。

使用vmstat

vmstat 1 5

每秒输出一次,共5次。关注 si(swap in)和 so(swap out)列:

procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 1  0 102400 123456  78900 456789    0    0    12    34  100  200 10  5 85  0  0

siso 持续大于 0,说明系统正在频繁换页,可能存在内存压力。

使用sar(需安装 sysstat)

sar -W 1 5

显示 Swap 活动统计:

Linux 5.4.0-xx-generic (hostname)    04/01/2025      _x86_64_        (4 CPU)

03:00:01 PM  pswpin/s pswpout/s
03:00:02 PM      0.00      0.00
03:00:03 PM      0.00      0.00
  • pswpin/s:每秒换入的页面数
  • pswpout/s:每秒换出的页面数

Java 应用与 Swap:实战代码示例

Java 应用,尤其是大型企业应用或微服务,往往消耗大量内存。合理配置 Swap 对保障 Java 应用稳定性至关重要。

下面是一个模拟内存压力的 Java 程序,用于测试系统在内存不足时如何触发 Swap。

示例 1:内存消耗器(MemoryHog.java)

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class MemoryHog {
    private static List<byte[]> memoryChunks = new ArrayList<>();
    public static void main(String[] args) {
        System.out.println("🚀 Java Memory Hog 启动");
        System.out.println("本程序将持续分配内存,直到系统内存耗尽或手动停止。");
        System.out.println("按回车键开始分配内存...");
        new Scanner(System.in).nextLine();
        int chunkSizeMB = 100; // 每次分配 100MB
        long totalAllocatedMB = 0;
        try {
            while (true) {
                byte[] chunk = new byte[chunkSizeMB * 1024 * 1024]; // 分配 100MB
                memoryChunks.add(chunk); // 保持引用防止 GC 回收
                totalAllocatedMB += chunkSizeMB;
                System.out.printf("✅ 已分配 %d MB 内存\n", totalAllocatedMB);
                // 每次分配后稍作休眠,便于观察系统状态
                Thread.sleep(1000);
            }
        } catch (OutOfMemoryError e) {
            System.err.println("💥 发生 OutOfMemoryError!");
            System.err.println("堆内存已耗尽。系统可能已开始使用 Swap 或终止进程。");
            e.printStackTrace();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            System.out.println("🛑 程序被中断");
        }
    }
}

编译与运行:

javac MemoryHog.java
java -Xmx4g MemoryHog  # 限制最大堆为 4GB

在另一个终端窗口中,你可以使用 free -hvmstat 1 实时观察 Swap 使用情况。

示例 2:监控 Swap 使用的 Java 工具类

以下是一个简单的 Java 工具类,用于在程序内部监控 Swap 使用情况(通过调用系统命令):

import java.io.BufferedReader;
import java.io.InputStreamReader;
public class SwapMonitor {
    public static void main(String[] args) throws Exception {
        System.out.println("📊 开始监控 Swap 使用情况(每5秒刷新)");
        while (true) {
            SwapInfo info = getSwapInfo();
            System.out.printf(
                "🕒 %s | 总计: %s | 已用: %s | 空闲: %s | 使用率: %.2f%%\n",
                java.time.LocalTime.now(),
                formatBytes(info.total),
                formatBytes(info.used),
                formatBytes(info.free),
                info.getUsagePercentage()
            );
            Thread.sleep(5000);
        }
    }
    public static SwapInfo getSwapInfo() throws Exception {
        Process process = Runtime.getRuntime().exec("free -b");
        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        String line;
        while ((line = reader.readLine()) != null) {
            if (line.startsWith("Swap:")) {
                String[] parts = line.split("\\s+");
                long total = Long.parseLong(parts[1]);
                long used = Long.parseLong(parts[2]);
                long free = Long.parseLong(parts[3]);
                return new SwapInfo(total, used, free);
            }
        }
        throw new RuntimeException("未找到 Swap 信息");
    }
    private static String formatBytes(long bytes) {
        if (bytes < 1024) return bytes + " B";
        else if (bytes < 1024 * 1024) return String.format("%.2f KB", bytes / 1024.0);
        else if (bytes < 1024 * 1024 * 1024) return String.format("%.2f MB", bytes / (1024.0 * 1024));
        else return String.format("%.2f GB", bytes / (1024.0 * 1024 * 1024));
    }
    static class SwapInfo {
        final long total, used, free;
        SwapInfo(long total, long used, long free) {
            this.total = total;
            this.used = used;
            this.free = free;
        }
        double getUsagePercentage() {
            if (total == 0) return 0.0;
            return (used * 100.0) / total;
        }
    }
}

此工具可用于长期运行的 Java 服务中,配合日志系统记录 Swap 使用趋势,帮助运维人员提前预警内存瓶颈。

Swap 与 JVM 参数调优

JVM 提供了丰富的内存管理参数,合理设置可以减少对 Swap 的依赖。

推荐 JVM 启动参数

java \
  -Xms2g \           # 初始堆大小
  -Xmx2g \           # 最大堆大小
  -XX:MaxMetaspaceSize=512m \  # 元空间上限
  -XX:+UseG1GC \     # 使用 G1 垃圾回收器
  -XX:MaxGCPauseMillis=200 \   # 目标最大 GC 暂停时间
  -XX:+AlwaysPreTouch \        # 启动时预分配并清零内存页,避免运行时缺页
  -XX:+DisableExplicitGC \     # 禁用 System.gc()
  -verbose:gc \                # 输出 GC 日志
  -XX:+PrintGCDetails \
  -XX:+PrintGCTimeStamps \
  -Xloggc:/var/log/myapp-gc.log \
  -Djava.awt.headless=true \
  -jar myapp.jar

AlwaysPreTouch 参数特别重要:它强制 JVM 在启动时就触碰(touch)所有堆内存页,促使操作系统立即分配物理内存或 Swap 空间,避免在高峰期因缺页中断导致延迟飙升。

Swap 对 Java 应用性能的影响分析

Swap 的使用对 Java 应用的性能影响主要体现在以下几个方面:

  1. GC 暂停时间增加:垃圾回收器需要扫描和移动对象,如果这些对象位于 Swap 中,I/O 延迟会导致 GC 暂停时间大幅增加。
  2. 响应时间不稳定:用户请求处理过程中若触发缺页中断,响应时间可能出现毛刺(spike)。
  3. 吞吐量下降:频繁的换页操作占用 I/O 带宽,降低整体吞吐能力。

因此,在生产环境中,应尽量避免 Java 进程使用 Swap。可以通过以下方式实现:

  • 为 JVM 分配合理的堆大小(不超过物理内存的 70%)
  • 启用 AlwaysPreTouch
  • 监控 Swap 使用率,设置告警阈值(如 > 10%)
  • 使用容器化部署时,设置内存限制并禁用 Swap(如 Docker 的 --memory-swappiness=0

容器环境中的 Swap 管理

在 Docker 或 Kubernetes 环境中,Swap 的行为有所不同。

Docker 中控制 Swap

docker run \
  --memory="2g" \
  --memory-swap="2g" \   # 等于内存 => 禁用 Swap
  --memory-swappiness=0 \ # 禁止容器使用 Swap
  my-java-app
  • --memory-swap:总内存限制(内存 + Swap)。设为与 --memory 相同值即禁用 Swap。
  • --memory-swappiness=0:完全禁止使用 Swap。

Kubernetes 中的资源限制

在 Pod 的 YAML 配置中:

apiVersion: v1
kind: Pod
metadata:
  name: java-app
spec:
  containers:
  - name: app
    image: my-java-image
    resources:
      limits:
        memory: "2Gi"
      requests:
        memory: "1.5Gi"

Kubernetes 默认不允许容器使用 Swap。若节点启用了 Swap,kubelet 会忽略它,除非显式配置 --fail-swap-on=false

故障排查:Swap 导致的问题诊断

当系统变慢或 Java 应用出现无响应时,Swap 往往是罪魁祸首之一。

诊断步骤:

检查 Swap 使用率

free -h

如果 Swap 使用率 > 50%,需警惕。

查看换页活动

vmstat 1 5

si/so 持续 > 100 KB/s,说明存在频繁换页。

找出占用 Swap 的进程

for file in /proc/*/status ; do
    awk '/VmSwap|Name/{printf $2 " " $3}END{ print ""}' $file 2>/dev/null
done | sort -k 2 -n -r | head -10

输出示例:

java 102400 kB
mysqld 51200 kB
nginx 1024 kB

查看具体进程的内存映射

cat /proc/<PID>/smaps | grep -i swap

可看到哪些内存区域被换出。

最佳实践总结

生产环境建议启用 Swap
即使内存充足,也应配置适量 Swap(如物理内存的 10%-20%),以防突发内存需求导致 OOM。

不要过度依赖 Swap
Swap 是“安全气囊”,不是“发动机”。频繁使用 Swap 表明系统设计或资源配置存在问题。

SSD 上的 Swap 性能更好
如果使用 Swap,尽量放在 SSD 上,并设置较高优先级。

Java 应用应预分配内存
使用 -XX:+AlwaysPreTouch 避免运行时缺页。

监控与告警
部署监控系统(如 Prometheus + Grafana),对 Swap 使用率、换页速率设置告警。

容器环境明确禁用 Swap
除非有特殊需求,否则在容器中禁用 Swap,确保资源隔离。

定期审查 Swap 配置
随着业务增长,定期评估是否需要调整 Swap 大小或升级物理内存。

附录:一键 Swap 管理脚本

以下是一个 Bash 脚本,用于快速创建、扩展或删除 Swap 文件:

#!/bin/bash
# swap-manager.sh - 简易 Swap 管理脚本
# 用法:./swap-manager.sh create 2G    # 创建 2GB Swap
#       ./swap-manager.sh resize 4G    # 调整为 4GB
#       ./swap-manager.sh remove       # 删除 Swap
SWAPFILE="/swapfile"
FSTAB="/etc/fstab"
case "$1" in
    create)
        SIZE="$2"
        if [ -z "$SIZE" ]; then
            echo "❌ 请指定大小,如:2G"
            exit 1
        fi
        echo "🔧 正在创建 $SIZE 的 Swap 文件..."
        sudo fallocate -l "$SIZE" "$SWAPFILE" || {
            echo "⚠️ fallocate 失败,尝试使用 dd..."
            sudo dd if=/dev/zero of="$SWAPFILE" bs=1M count=$(echo "$SIZE" | sed 's/G/*1024/' | bc)
        }
        sudo chmod 600 "$SWAPFILE"
        sudo mkswap "$SWAPFILE"
        sudo swapon "$SWAPFILE"
        # 添加到 fstab
        if ! grep -q "$SWAPFILE" "$FSTAB"; then
            echo "$SWAPFILE none swap sw 0 0" | sudo tee -a "$FSTAB" > /dev/null
        fi
        echo "✅ Swap 已启用:$(free -h | grep Swap)"
        ;;
    resize)
        SIZE="$2"
        if [ -z "$SIZE" ]; then
            echo "❌ 请指定新大小,如:4G"
            exit 1
        fi
        echo "🔄 正在调整 Swap 大小至 $SIZE..."
        sudo swapoff "$SWAPFILE"
        sudo rm "$SWAPFILE"
        sudo fallocate -l "$SIZE" "$SWAPFILE" || {
            sudo dd if=/dev/zero of="$SWAPFILE" bs=1M count=$(echo "$SIZE" | sed 's/G/*1024/' | bc)
        }
        sudo chmod 600 "$SWAPFILE"
        sudo mkswap "$SWAPFILE"
        sudo swapon "$SWAPFILE"
        echo "✅ Swap 已调整:$(free -h | grep Swap)"
        ;;
    remove)
        echo "🗑️  正在移除 Swap..."
        sudo swapoff "$SWAPFILE"
        sudo rm "$SWAPFILE"
        # 从 fstab 中删除
        sudo sed -i "\|^$SWAPFILE|d" "$FSTAB"
        echo "✅ Swap 已移除"
        ;;
    *)
        echo "用法:$0 {create|resize|remove} [size]"
        echo "示例:"
        echo "  $0 create 2G"
        echo "  $0 resize 4G"
        echo "  $0 remove"
        ;;
esac

保存为 swap-manager.sh,赋予执行权限:

chmod +x swap-manager.sh

即可方便地管理 Swap 文件。

结语

Swap 是 Linux 系统内存管理的重要组成部分,尤其在运行内存密集型 Java 应用时,合理配置 Swap 能显著提升系统稳定性和容错能力。通过本文的学习,你已经掌握了 Swap 的创建、调整、监控和优化方法,并能结合 Java 应用进行实战调优。

记住:Swap 不是性能的敌人,滥用才是。 正确理解和使用 Swap,让它成为你系统架构中的“守护者”,而非“拖油瓶”。

以上就是Linux swap交换分区的创建与调整方案的详细内容,更多关于Linux swap交换分区创建与调整的资料请关注脚本之家其它相关文章!

相关文章

  • Linux文件操作新手指南之关于install命令的用法

    Linux文件操作新手指南之关于install命令的用法

    这篇文章主要介绍了Linux文件操作新手指南之关于install命令的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-02-02
  • Linux文件系统之缓冲区详解

    Linux文件系统之缓冲区详解

    在 Linux 中,缓冲区通常指的是用于临时存储数据的内存区域,它可以用来提高系统性能,Linux 中有多种类型的缓冲区,包括文件系统缓冲区、网络缓冲区等,本文给大家详细介绍了Linux文件系统之缓冲区,感兴趣的朋友可以参考下
    2024-02-02
  • Yum安装中出现错误mirrorlist.txt的解决方法

    Yum安装中出现错误mirrorlist.txt的解决方法

    前几天在使用Yum install命令安装软件的时候一直提示一个mirrorlist.txt错误,通过查找相关的资料现在找到了解决的方法,所以这篇文章就整理出来和大家分享一下,有同样遇到这个问题的朋友们可以参考借鉴下。
    2016-10-10
  • Centos7配置与安装DNS服务器全过程

    Centos7配置与安装DNS服务器全过程

    这篇文章主要介绍了Centos7配置与安装DNS服务器全过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-09-09
  • 最完的htaccess文件用法收集整理

    最完的htaccess文件用法收集整理

    最完的htaccess文件用法收集,这篇文章确实很详细,需要的朋友可以参考下
    2012-05-05
  • Linux 7.4上安装配置Oracle 11.2.0.4图文教程

    Linux 7.4上安装配置Oracle 11.2.0.4图文教程

    本文通过图文并茂的形式给大家介绍了Linux 7.4上安装配置Oracle 11.2.0.4的方法,非常不错,具有参考借鉴价值,需要的朋友参考下吧
    2017-12-12
  • 在Unix/Linux上使用通用二进制文件安装MySQL方式

    在Unix/Linux上使用通用二进制文件安装MySQL方式

    本文介绍了如何在Unix/Linux平台上从压缩的tar文件二进制发行版安装MySQL,首先,需要下载并解压缩发行版,然后创建一个符号链接并将其添加到PATH变量中,接下来,设置发行版的所有权和访问权限,初始化数据目录,启动MySQL服务器,并设置配置文件
    2025-02-02
  • Linux netstat命令安装方式

    Linux netstat命令安装方式

    这篇文章主要介绍了Linux netstat命令安装方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • linux系统之如何禁用usb口

    linux系统之如何禁用usb口

    这篇文章主要介绍了linux系统之如何禁用usb口问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-06-06
  • CentOS 7 下LAMP实现及基于https的虚拟化主机

    CentOS 7 下LAMP实现及基于https的虚拟化主机

    这篇文章主要介绍了CentOS 7 下LAMP实现及基于https的虚拟化主机的相关资料,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2016-11-11

最新评论