swap 说明

本文详细解释了Linux系统中Swap空间的作用、如何调整以提升性能,以及突破传统128MB限制的方法。重点讨论了Swap配置对系统性能的影响,并提供了Swap空间分配的建议,包括不同应用需求下的配置方案。同时,介绍了Swap操作的相关系统命令,以及如何监控Swap使用情况,确保系统性能维持在合理范围内。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 swap简介
    Swap,即交换区,除了安装Linux的时候,有多少人关心过它呢?其实,Swap的调整对Linux服务器,特别是Web服务器的性能至关重要。通过调整Swap,有时可以越过系统性能瓶颈,节省系统升级费用。  
    众所周知,现代操作系统都实现了“虚拟内存”这一技术,不但在功能上突破了物理内存的限制,使程序可以操纵大于实际物理内存的空间,更重要的是,“虚拟内存”是隔离每个进程的安全保护网,使每个进程都不受其它程序的干扰。  

    Swap空间的作用可简单描述为:当系统的物理内存不够用的时候,就需要将物理内存中的一部分空间释放出来,以供当前运行的程序使用。那些被释放的空间可能来自一些很长时间没有什么操作的程序,这些被释放的空间被临时保存到Swap空间中,等到那些程序要运行时,再从Swap中恢复保存的数据到内存中。这样,系统总是在物理内存不够时,才进行Swap交换。  

    计算机用户会经常遇这种现象。例如,在使用Windows系统时,可以同时运行多个程序,当你切换到一个很长时间没有理会的程序时,会听到硬盘“哗哗”直响。这是因为这个程序的内存被那些频繁运行的程序给“偷走”了,放到了Swap区中。因此,一旦此程序被放置到前端,它就会从Swap区取回自己的数据,将其放进内存,然后接着运行。  

    需要说明一点,并不是所有从物理内存中交换出来的数据都会被放到Swap中(如果这样的话,Swap就会不堪重负),有相当一部分数据被直接交换到文件系统。例如,有的程序会打开一些文件,对文件进行读写(其实每个程序都至少要打开一个文件,那就是运行程序本身),当需要将这些程序的内存空间交换出去时,就没有必要将文件部分的数据放到Swap空间中了,而可以直接将其放到文件里去。如果是读文件操作,那么内存数据被直接释放,不需要交换出来,因为下次需要时,可直接从文件系统恢复;如果是写文件,只需要将变化的数据保存到文件中,以便恢复。但是那些用malloc和new函数生成的对象的数据则不同,它们需要Swap空间,因为它们在文件系统中没有相应的“储备”文件,因此被称作“匿名”(Anonymous)内存数据。这类数据还包括堆栈中的一些状态和变量数据等。所以说,Swap空间是“匿名”数据的交换空间。  

突破128M Swap限制  

在Linux系统下,这个虚拟内存就被叫做swap。Linux swap分区是有限制的。在安装操作系统的时候,安装向导会提示用户需要创建多少的SWaP空间。通常情况下,SWaP比较合适的大小为物理内存的1-2倍。

1. 早期的linux对虚拟内存的限制

    linux2.2以前的内核,支持最大128M的Linux swap分区或文件。Linux swap的分区或文件总数不超过16个。所以在linux2.2以前,可用的最大虚拟内存为128M*8=1G.

   Swap空间是分页的,每一页的大小和内存页的大小相同,方便Swap空间和内存之间的数据交换。旧版本的Linux实现Swap空间时,用Swap空间的第一页作为任何Swap空间页的一个“位映射”(Bit map)。这就是说第一页的每一位,都对应着一页Swap空间。假如这一位是1,表示此页Swap可用;假如是0,表示此页是坏块,不能使用。这么说来,第一个Swap映射位应该是0,因为,第一页Swap是映射页。另外,最后10个映射位也被占用,用来表示Swap的版本(原来的版本是Swap_space ,现在的版本是swapspace2)。那么,假如说一页的大小为s,这种Swap的实现方法共能管理“8 * ( s - 10 ) - 1”个Swap页。对于i386系统来说s=4096,则空间大小共为133890048,假如认为1 MB=2^20 Byte的话,大小正好为128M。

之所以这样来实现Swap空间的管理,是要防止Swap空间中有坏块。假如系统检查到Swap中有坏块,则在相应的位映射上标记上0,表示此页不可用。这样在使用Swap时,不至于用到坏块,而使系统产生错误。

2. Linux2.2.x对虚拟内存的限制

现在的系统设计者认为: 

1.现在硬盘质量很好,坏块很少。 

2.就算有,也不多,只需要将坏块罗列出来,而无需为每一页建立映射。 

3.假如有很多坏块,就不应该将此硬盘作为Swap空间使用。 

于是,现在的Linux取消了位映射的方法,也就取消了128M的限制。直接用地址访问,限制为2G。 

Linux2.2.x支持最大2G的Linux swap分区或文件。Linux swap的分区或文件总数不超过8个。所以在Linux2.2.x,可用的最大虚拟内存为 2G*8=16G

 

3. Linux2.4.x对虚拟内存的限制

Linux2.4.10之前支持最大2G的Linux swap分区或文件。Linux swap的分区或文件总数不超过8个。所以在 Linux2.4.10之前,可用的最大虚拟内存为 2G*8=16G

Linux2.4.10(含)之后支持最大2G的Linux swap分区或文件。Linux swap的分区或文件总数不超过32个。所以在 Linux2.4.10之后,可用的最大虚拟内存为 2G*32=64G

Linux2.4.x在内存管理策略上,就如Windows98向Windows2000转变一样,在内存和交换区中保存了更多的脏页,而不是及时回收内存,以此提高系统的效率。

此外,如果你有超过1块磁盘,并且分别在不同的磁盘上建立了Linux swap,那么linux会按照raid 0的方式来使用这些交换分区。

Swap配置对性能的影响 分配太多的Swap空间会浪费磁盘空间,而Swap空间太少,则系统会发生错误。 如果系统的物理内存用光了,系统就会跑得很慢,但仍能运行;如果Swap空间用光了,那么系统就会发生错误。例如,Web服务器能根据不同的请求数量衍生出多个服务进程(或线程),如果Swap空间用完,则服务进程无法启动,通常会出现“application is out of memory”的错误,严重时会造成服务进程的死锁。因此Swap空间的分配是很重要的。 通常情况下,Swap空间应大于或等于物理内存的大小,最小不应小于64M,通常Swap空间的大小应是物理内存的2-2.5倍。但根据不同的应用,应有不同的配置:如果是小的桌面系统,则只需要较小的Swap空间,而大的服务器系统则视情况不同需要不同大小的Swap空间。特别是数据库服务器和Web服务器,随着访问量的增加,对Swap空间的要求也会增加,具体配置参见各服务器产品的说明。 另外,Swap分区的数量对性能也有很大的影响。因为Swap交换的操作是磁盘IO的操作,如果有多个Swap交换区,Swap空间的分配会以轮流的方式操作于所有的Swap,这样会大大均衡IO的负载,加快Swap交换的速度。如果只有一个交换区,所有的交换操作会使交换区变得很忙,使系统大多数时间处于等待状态,效率很低。用性能监视工具就会发现,此时的CPU并不很忙,而系统却慢。这说明,瓶颈在IO上,依靠提高CPU的速度是解决不了问题的。 系统性能监视 Swap空间的分配固然很重要,而系统运行时的性能监控却更加有价值。通过性能监视工具,可以检查系统的各项性能指标,找到系统性能的瓶颈。本文只介绍一下在Solaris下和Swap相关的一些命令和用途。 最常用的是Vmstat命令(在大多数Unix平台下都有这样一些命令),此命令可以查看大多数性能指标。 例如: # vmstat 3 procs memory swap io system cpu r b w swpd free buff cache si so bi bo in cs us sy id 0 0 0 0 93880 3304 19372 0 0 10 2 131 10 0 0 99 0 0 0 0 93880 3304 19372 0 0 0 0 109 8 0 0 100 0 0 0 0 93880 3304 19372 0 0 0 0 112 6 0 0 100 ………… 命令说明: vmstat 后面的参数指定了性能指标捕获的时间间隔。3表示每三秒钟捕获一次。第一行数据不用看,没有价值,它仅反映开机以来的平均性能。从第二行开始,反映每三秒钟之内的系统性能指标。这些性能指标中和Swap有关的包括以下几项: procs下的w 它表示当前(三秒钟之内)需要释放内存、交换出去的进程数量。 memory下的swpd 它表示使用的Swap空间的大小。 Swap下的si,so si表示当前(三秒钟之内)每秒交换回内存(Swap in)的总量,单位为kbytes;so表示当前(三秒钟之内)每秒交换出内存(Swap out)的总量,单位为kbytes。 以上的指标数量越大,表示系统越忙。这些指标所表现的系统繁忙程度,与系统具体的配置有关。系统管理员应该在平时系统正常运行时,记下这些指标的数值,在系统发生问题的时候,再进行比较,就会很快发现问题,并制定本系统正常运行的标准指标值,以供性能监控使用。 另外,使用Swapon-s也能简单地查看当前Swap资源的使用情况。例如: # swapon -s Filename Type Size Used Priority /dev/hda9 partition 361420 0 3 能够方便地看出Swap空间的已用和未用资源的大小。 应该使Swap负载保持在30%以下,这样才能保证系统的良好性能。 有关Swap操作的系统命令 增加Swap空间,分以下几步: 1)成为超级用户 $su - root 2)创建Swap文件 # dd if=/dev/zero of=swapfile bs=1024 count=65536 创建一个有连续空间的交换文件。 3)激活Swap文件 #/usr/sbin/swapon swapfile swapfile指的是上一步创建的交换文件。 4)现在新加的Swap文件已经起作用了,但系统重新启动以后,并不会记住前几步的操作。因此要在/etc/fstab文件中记录文件的名字,和Swap类型,如: /path/swapfile none Swap sw,pri=3 0 0 5)检验Swap文件是否加上 /usr/sbin/swapon -s 删除多余的Swap空间。 1)成为超级用户 2)使用Swapoff命令收回Swap空间。 #/usr/sbin/swapoff swapfile 3)编辑/etc/fstab文件,去掉此Swap文件的实体。 4)从文件系统中回收此文件。 #rm swapfile 5)当然,如果此Swap空间不是一个文件,而是一个分区,则需创建一个新的文件系统,再挂接到原来的文件系统上。
<think>好的,用户想了解C++中swap函数的用法和示例。首先,我需要回忆C++标准库中的swap函数。标准库中的std::swap是一个模板函数,位于<utility>头文件中,用于交换两个同类型对象的值。这个函数在C++11之后有移动语义的支持,提高了效率。 接下来,用户可能需要知道基本用法,比如如何交换基本数据类型、容器等。比如交换int、double,或者std::vector、std::string。这里可以举几个例子,比如交换两个整数,交换两个vector容器,这些例子能展示swap的高效性,特别是对于容器来说,交换指针而不是元素,时间复杂度是O(1)。 然后,用户可能关心自定义类型的swap。这时候需要说明如何为自定义类重载swap函数,或者提供特化版本。需要注意ADL(参数依赖查找),以及友元函数的使用,确保swap能在正确的作用域被调用。此外,移动语义的优化也很重要,可以避免不必要的拷贝。 还有,用户可能想知道在STL容器中的swap成员函数,比如std::vector::swap,这和std::swap的区别。需要指出成员函数swap可能有更高的效率,因为直接操作内部数据结构,而std::swap通用但可能依赖移动构造函数。 可能用户也会对性能优化感兴趣,比如使用swap来释放内存,比如通过和临时空容器交换来收缩容量。这时候可以举一个vector的例子,说明如何通过swap来减少内存占用。 另外,可能需要提到异常安全性和noexcept修饰符,特别是在C++11之后,移动操作通常标记为noexcept,这样swap在标准容器中更高效,比如std::vector的swap需要保证不抛出异常。 然后,检查是否有相关引用可以链接。根据用户提供的引用,引用[1]提到代理类,可能和swap的实现无关;引用[2]关于模板,std::swap正是模板函数的一个例子;引用[3]可能不相关。所以引用[2]可以用来支持std::swap作为模板的例子。 最后,生成相关问题需要考虑用户可能的后续疑问,比如自定义类型的swap实现,性能对比,异常处理,以及应用场景如内存管理。这样可以覆盖用户潜在的需求。</think>### C++中swap函数的用法与示例 C++标准库中的$swap$函数用于交换两个对象的值,其核心实现基于移动语义或拷贝操作。根据不同的应用场景,$swap$函数在基础数据类型、容器类、自定义类中均有广泛使用。 --- #### 1. 基本用法(标准库模板函数) 通过$<utility>$头文件引入,支持任意类型的交换: ```cpp #include <utility> int a = 10, b = 20; std::swap(a, b); // 交换后 a=20, b=10 std::vector<int> v1{1,2,3}, v2{4,5}; std::swap(v1, v2); // 交换容器内容(时间复杂度O(1)) ``` **说明**:对于STL容器(如$std::vector$),交换操作仅交换内部指针,时间复杂度为$O(1)$[^2]。 --- #### 2. 自定义类型优化 为自定义类实现高效的$swap$函数: ```cpp class MyData { public: MyData(const std::string& s) : data(s) {} friend void swap(MyData& a, MyData& b) noexcept { using std::swap; swap(a.data, b.data); // 利用ADL规则调用最佳swap } private: std::string data; }; // 使用示例 MyData obj1("Hello"), obj2("World"); swap(obj1, obj2); // 调用自定义swap ``` **关键点**: - 通过友元函数实现,支持参数依赖查找(ADL) - 使用$noexcept$优化移动语义 --- #### 3. STL容器的swap成员函数 部分容器(如$std::vector$)提供专用成员函数: ```cpp std::vector<int> vecA{1,2}, vecB{3,4,5}; vecA.swap(vecB); // vecA容量变为3,vecB容量变为2 ``` **优势**:直接操作容器内部存储,避免模板实例化开销。 --- #### 4. 应用场景与技巧 - **内存释放**:通过交换清空容器内存 ```cpp std::vector<int> large_vec(1000000); std::vector<int>().swap(large_vec); // 强制释放内存 ``` - **异常安全**:在拷贝赋值运算符中实现强异常安全保证 ```cpp MyData& operator=(MyData other) { swap(*this, other); return *this; } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值