今天我们来谈谈 Linux 的内存机制
首先我们理一下概念
一什么是 linux 的内存机制?
我们知道, 直接从物理内存读写数据要比从硬盘读写数据要快的多, 因此, 我们希望所有数据的读取和写入都在内存完成, 而内存是有限的, 这样就引出了物理内存与虚拟内存的概念
物理内存就是系统硬件提供的内存大小, 是真正的内存, 相对于物理内存, 在 linux 下还有一个虚拟内存的概念, 虚拟内存就是为了满足物理内存的不足而提出的策略, 它是利用磁盘空间虚拟出的一块逻辑内存, 用作虚拟内存的磁盘空间被称为交换空间(Swap Space)
作为物理内存的扩展, linux 会在物理内存不足时, 使用交换分区的虚拟内存, 更详细的说, 就是内核会将暂时不用的内存块信息写到交换空间, 这样以来, 物理内存得到了释放, 这块内存就可以用于其它目的, 当需要用到原始的内容时, 这些信息会被重新从交换空间读入物理内存
Linux 的内存管理采取的是分页存取机制, 为了保证物理内存能得到充分的利用, 内核会在适当的时候将物理内存中不经常使用的数据块自动交换到虚拟内存中, 而将经常使用的信息保留到物理内存
要深入了解 linux 内存运行机制, 需要知道下面提到的几个方面:
Linux 系统会不时的进行页面交换操作, 以保持尽可能多的空闲物理内存, 即使并没有什么事情需要内存, Linux 也会交换出暂时不用的内存页面这可以避免等待交换所需的时间
Linux 进行页面交换是有条件的, 不是所有页面在不用时都交换到虚拟内存, linux 内核根据最近最经常使用算法, 仅仅将一些不经常使用的页面文件交换到虚拟 内存, 有时我们会看到这么一个现象: linux 物理内存还有很多, 但是交换空间也使用了很多其实, 这并不奇怪, 例如, 一个占用很大内存的进程运行时, 需 要耗费很多内存资源, 此时就会有一些不常用页面文件被交换到虚拟内存中, 但后来这个占用很多内存资源的进程结束并释放了很多内存时, 刚才被交换出去的页面 文件并不会自动的交换进物理内存, 除非有这个必要, 那么此刻系统物理内存就会空闲很多, 同时交换空间也在被使用, 就出现了刚才所说的现象了关于这点, 不 用担心什么, 只要知道是怎么一回事就可以了
交换空间的页面在使用时会首先被交换到物理内存, 如果此时没有足够的物理内存来容纳这些页 面, 它们又会被马上交换出去, 如此以来, 虚拟内存中可能没有足够空间来存储这些交换页面, 最终会导致 linux 出现假死机服务异常等问题, linux 虽 然可以在一段时间内自行恢复, 但是恢复后的系统已经基本不可用了
因此, 合理规划和设计 Linux 内存的使用, 是非常重要的.
在 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 什么时候开始使用虚拟内存(swap)?
- A.[root@wenwen ~]# cat /proc/sys/vm/swappiness
- 60
上面这个 60 代表物理内存在使用 60% 的时候才会使用 swap
swappiness=0 的时候表示最大限度使用物理内存, 然后才是 swap 空间,
swappiness=100 的时候表示积极的使用 swap 分区, 并且把内存上的数据及时的搬运到 swap 空间里面
通常情况下:
swap 分区设置建议是内存的两倍 (内存小于等于 4G 时), 如果内存大于 4G,swap 只要比内存大就行另外尽量的将 swappiness 调低, 这样系统的性能会更好
B. 修改 swappiness 参数
临时性修改:
- [root@wenwen ~]# sysctl vm.swappiness=10
- vm.swappiness = 10
- [root@wenwen ~]# cat /proc/sys/vm/swappiness
- 10
永久性修改:
[root@wenwen ~]# vim /etc/sysctl.conf
加入参数:
vm.swappiness = 35
然后在直接:
[root@wenwen ~]# sysctl -p
查看是否生效:
- cat /proc/sys/vm/swappiness
- 35
三怎么释放内存?
一般系统是不会自动释放内存的
关键的配置文件 / proc/sys/vm/drop_caches 这个文件中记录了缓存释放的参数, 默认值为 0, 也就是不释放缓存他的值可以为 0~3 之间的任意数字, 代表着不同的含义:
0 不释放
1 释放页缓存
2 释放 dentries 和 inodes
3 释放所有缓存
实操:
很明显多出来很多空闲的内存了吧
四怎么释放 swap?
前提: 首先要保证内存剩余要大于等于 swap 使用量, 否则会宕机! 根据内存机制, swap 分区一旦释放, 所有存放在 swap 分区的文件都会转存到物理内存上通常通过重新挂载 swap 分区完成释放 swap
a. 查看当前 swap 分区挂载在哪?
b. 关停这个分区
c. 查看状态:
d. 查看 swap 分区是否关停, 最下面一行显示全 0
e. 将 swap 挂载到 / dev/sda5 上
f. 查看挂载是否成功
五一些实际的小例子?
我在设置 mysql 的时候, 将
my.cnf 文件
innodb_buffer_pool_size = 6G(我操作系统的内存就是 6G, 一般这个值设置为操作系统内存的 80%)
这个值并不是设置的越大越好设置的过大, 会导致 system 的 swap 空间被占用, 导致操作系统变慢, 从而减低 sql 查询的效率
这里你可以这么理解, 当我将这个 buffer_pool_size 设置得过大, 跟操作系统内存一样大的时候, 我使用 mysql, 会在一段时间内调用大量的数据进内存, 由于 linux 的内存机制, 再根据最近最优的原则, 将一部分数据筛选放入 swap 分区, 而 swap 分区没有及时的清理掉数据, 当再次调用其它数据的时候, 又会将一部分数据筛选放入 swap 分区, 可能会出现一个现象, 就是物理内存还有剩余, 甚至是空的, 而 swap 分区却是满的
来源: https://www.cnblogs.com/Zfc-Cjk/p/8447270.html