一 物理内存和虚拟内存
我们知道, 直接从物理内存读写数据要比从硬盘读写数据要快的多, 因此, 我们希望所有数据的读取和写入都在内存完成, 而内存是有限的, 这样就引出了物理内存与虚拟内存的概念
物理内存就是系统硬件提供的内存大小, 是真正的内存, 相对于物理内存, 在 linux 下还有一个虚拟内存的概念, 虚拟内存就是为了满足物理内存的不足而提出的策略, 它是利用磁盘空间虚拟出的一块逻辑内存, 用作虚拟内存的磁盘空间被称为交换空间(Swap Space)
作为物理内存的扩展, linux 会在物理内存不足时, 使用交换分区的虚拟内存, 更详细的说, 就是内核会将暂时不用的内存块信息写到交换空间, 这样以来, 物理内存得到了释放, 这块内存就可以用于其它目的, 当需要用到原始的内容时, 这些信息会被重新从交换空间读入物理内存
linux 的内存管理采取的是分页存取机制, 为了保证物理内存能得到充分的利用, 内核会在适当的时候将物理内存中不经常使用的数据块自动交换到虚拟内存中, 而将经常使用的信息保留到物理内存
要深入了解 linux 内存运行机制, 需要知道下面提到的几个方面:
首先, Linux 系统会不时的进行页面交换操作, 以保持尽可能多的空闲物理内存, 即使并没有什么事情需要内存, Linux 也会交换出暂时不用的内存页面这可以避免等待交换所需的时间
其次, linux 进行页面交换是有条件的, 不是所有页面在不用时都交换到虚拟内存, linux 内核根据最近最经常使用算法, 仅仅将一些不经常使用的页面文件交换到虚拟内存, 有时我们会看到这么一个现象: linux 物理内存还有很多, 但是交换空间也使用了很多其实, 这并不奇怪, 例如, 一个占用很大内存的进程运行时, 需要耗费很多内存资源, 此时就会有一些不常用页面文件被交换到虚拟内存中, 但后来这个占用很多内存资源的进程结束并释放了很多内存时, 刚才被交换出去的页面文件并不会自动的交换进物理内存, 除非有这个必要, 那么此刻系统物理内存就会空闲很多, 同时交换空间也在被使用, 就出现了刚才所说的现象了关于这点, 不用担心什么, 只要知道是怎么一回事就可以了
最后, 交换空间的页面在使用时会首先被交换到物理内存, 如果此时没有足够的物理内存来容纳这些页面, 它们又会被马上交换出去, 如此以来, 虚拟内存中可能没有足够空间来存储这些交换页面, 最终会导致 linux 出现假死机服务异常等问题, linux 虽然可以在一段时间内自行恢复, 但是恢复后的系统已经基本不可用了
因此, 合理规划和设计 linux 内存的使用, 是非常重要的.
二 内存的监控
作为一名 linux 系统管理员, 监控内存的使用状态是非常重要的, 通过监控有助于了解内存的使用状态, 比如内存占用是否正常, 内存是否紧缺等等, 监控内存最常使用的命令有 freetop 等, 下面是某个系统 free 的输出:
- [haixigov@webServer ~]$ free
- total used free shared buffers cached
- Mem: 16402432 16360492 41940 0 465404 12714880
- -/+ buffers/cache: 3180208 13222224
- Swap: 8193108 264 8192844
我们解释下输出结果中每个选项的含义:
首先是第一行:
? total: 物理内存的总大小
? used: 已经使用的物理内存多小
? free: 空闲的物理内存值
? shared: 多个进程共享的内存值
? buffers/cached: 磁盘缓存的大小
第二行 Mem: 代表物理内存使用情况
第三行(-/+ buffers/cached): 代表磁盘缓存使用状态
第四行: Swap 表示交换空间内存使用状态
free 命令输出的内存状态, 可以通过两个角度来查看: 一个是从内核的角度来看, 一个是从应用层的角度来看的
1.从内核的角度来查看内存的状态
就是内核目前可以直接分配到, 不需要额外的操作, 即为上面 free 命令输出中第二行 Mem 项的值, 可以看出, 此系统物理内存有 16G, 空闲的内存只有 41940K, 也就是 40M 多一点, 我们来做一个这样的计算:
16402432-16360492=41940
其实就是总的物理内存减去已经使用的物理内存得到的就是空闲的物理内存大小, 注意这里的可用内存值 41940 并不包含处于 buffers 和 cached 状态的内存大小
如果你认为这个系统空闲内存太小, 那你就错了, 实际上, 内核完全控制着内存的使用情况, linux 会在需要内存的时候, 或在系统运行逐步推进时, 将 buffers 和 cached 状态的内存变为 free 状态的内存, 以供系统使用
2.从应用层的角度来看系统内存的使用状态
也就是 linux 上运行的应用程序可以使用的内存大小, 即 free 命令第三行 (-/+ buffers/cached) 的输出, 可以看到, 此系统已经使用的内存才 3180208K, 而空闲的内存达到 13222224K, 继续做这样一个计算:
41940+(465404+12714880)=13222224
通过这个等式可知, 应用程序可用的物理内存值是 Mem 项的 free 值加上 buffers 和 cached 值之和, 也就是说, 这个 free 值是包括 buffers 和 cached 项大小的,
对于应用程序来说, buffers/cached 占有的内存是可用的, 因为 buffers/cached 是为了提高文件读取的性能, 当应用程序需要用到内存的时候, buffers/cached 会很快地被回收, 以供应用程序使用
3.buffers 与 cached 的异同
在 Linux 操作系统中, 当应用程序需要读取文件中的数据时, 操作系统先分配一些内存, 将数据从磁盘读入到这些内存中, 然后再将数据分发给应用程序; 当需要往文件中写数据时, 操作系统先分配内存接收用户数据, 然后再将数据从内存写到磁盘上然而, 如果有大量数据需要从磁盘读取到内存或者由内存写入磁盘时, 系统的读写性能就变得非常低下, 因为无论是从磁盘读数据, 还是写数据到磁盘, 都是一个很消耗时间和资源的过程, 在这种情况下, linux 引入了 buffers 和 cached 机制
buffers 与 cached 都是内存操作, 用来保存系统曾经打开过的文件以及文件属性信息, 这样当操作系统需要读取某些文件时, 会首先在 buffers 与 cached 内存区查找, 如果找到, 直接读出传送给应用程序, 如果没有找到需要数据, 才从磁盘读取, 这就是操作系统的缓存机制, 通过缓存, 大大提高了操作系统的性能但 buffers 与 cached 缓冲的内容却是不同的
buffers 是用来缓冲块设备做的, 它只记录文件系统的元数据 (metadata) 以及 tracking in-flight pages, 而 cached 是用来给文件做缓冲更通俗一点说: buffers 主要用来存放目录里面有什么内容, 文件的属性以及权限等等而 cached 直接用来记忆我们打开过的文件和程序
为了验证我们的结论是否正确, 可以通过 vi 打开一个非常大的文件, 看看 cached 的变化, 然后再次 vi 这个文件, 感觉一下两次打开的速度有何异同, 是不是第二次打开的速度明显快于第一次呢?
接着执行下面的命令:
find /* -name *.conf
看看 buffers 的值是否变化, 然后重复执行 find 命令, 看看两次显示速度有何不同
Linux 操作系统的内存运行原理, 很大程度上是根据服务器的需求来设计的, 例如系统的缓冲机制会把经常使用到的文件和数据缓存在 cached 中, linux 总是在力求缓存更多的数据和信息, 这样再次需要这些数据时可以直接从内存中取, 而不需要有一个漫长的磁盘操作, 这种设计思路提高了系统的整体性能
三 交换空间 swap 的使用
虽然现在的内存已经变得非常廉价, 但是 swap 仍然有很大的使用价值, 合理的规划和使用 swap 分区, 对系统稳定运行至关重要 Linux 下可以使用文件系统中的一个常规文件或者一个独立分区作为交换空间使用同时 linux 允许使用多个交换分区或者交换文件
1.创建 swap 交换空间
创建交换空间所需的交换文件是一个普通的文件, 但是, 创建交换文件与创建普通文件不同, 必须通过 dd 命令来完成, 同时这个文件必须位于本地硬盘上, 不能在网络文件系统 (NFS) 上创建 swap 交换文件例如:
- [root@localhost ~]# dd if=/dev/zero of=/data/swapfile bs=1024 count=65536
- 65536+0 records in
- 65536+0 records out
这样就创建一个有连续空间的交换文件, 大小为 60M 左右, 关于 dd 命令做简单的讲述:
if = 输入文件, 或者设备名称
of = 输出文件或者设备名称
ibs=bytes 表示一次读入 bytes 个字节(即一个块大小为 bytes 个字节)
obs=bytes 表示一次写 bytes 个字节(即一个块大小为 bytes 个字节)
bs=bytes, 同时设置读写块的大小, 以 bytes 为单位, 此参数可代替 ibs 和 obs
count=blocks 仅拷贝 blocks 个块
skip=blocks 表示从输入文件开头跳过 blocks 个块后再开始复制
seek=blocks 表示从输出文件开头跳过 blocks 个块后再开始复制(通常只有当输出文件是磁盘或磁带时才有效)
这里的输入设备 / dev/zero 代表一个输出永远为 0 的设备文件, 使用它作输入可以得到全为空的文件
2.激活和使用 swap
首先通过 mkswap 命令指定作为交换空间的设备或者文件:
- [root@localhost ~]#mkswap /data/swapfile
- Setting up swapspace version 1, size = 67104 kB
- [root@localhost backup]# free
- total used free shared buffers cached
- Mem: 2066632 1998188 68444 0 26160 1588044
- -/+ buffers/cache: 383984 1682648
- Swap: 4088500 101036 3987464
从上面输出可知, 我们指定了一个 67104 kB 的交换空间, 而此时新建的交换空间还未被使用, 下面简单介绍下 mkswap 命令, mkswap 的一般使用格式为:
mkswap [参数] [设备名称或文件][交换区大小]
参数:
-c: 建立交换区前, 先检查是否有损坏的区块
-v0: 建立旧式交换区, 此为预设值
-v1: 建立新式交换区
交换区大小: 指定交换区的大小, 单位为 1024 字节
设置交换分区后, 接着通过 swapon 命令激活 swap:
- [root@localhost ~]#/usr/sbin/swapon /data/swapfile
- [root@localhost backup]# free
- total used free shared buffers cached
- Mem: 2066632 1997668 68964 0 27404 1588880
- -/+ buffers/cache: 381384 1685248
- Swap: 4154028 100976 4053052
通过 free 命令可以看出, swap 大小已经由 4088500k 变为 4154028k, 相差的值是 60M 左右, 刚好等于我们增加的一个交换文件大小, 这说明新增的交换分区已经可以使用了, 但是如果 linux 重启, 那么新增的 swap 空间将变得不可用, 因此需要在 / etc/fstab 中添加自动加载设置:
/data/swapfile none swap sw 0 0
如此以来, linux 在重启后就可以实现自动加载 swap 分区了其实 linux 在启动过程中会执行 swapon -a 命令, 此命令会加载列在 / etc/fstab 中的所有交换空间
3.移除 swap
通过 swapoff 即可移除一个交换空间
[root@localhost ~]#/usr/sbin/swapoff /data/swapfile
其实也可以通过 swapoff -a 移除在 / etc/fstab 中定义的所有交换空间, 这里的 swapoff -a 与上面提到的 swapon -a 对应执行 swapoff -a 后, free 命令输出如下:
- [root@localhost backup]# free
- total used free shared buffers cached
- Mem: 2066632 2048724 17908 0 30352 1642748
- -/+ buffers/cache: 375624 1691008
- Swap: 0 0 0
来源: http://www.bubuko.com/infodetail-2503099.html