细心的朋友会注意到, 当你在 Linux 下频繁存取文件后, 物理内存会很快被用光, 当程序结束后, 内存不会被正常释放, 而是一直作为 caching. 这个问题, 貌似有不少人在问, 不过都没有看到有什么很好解决的办法. 那么我来谈谈这个问题.
先来说说 free 命令
其中:
total 内存总数
used 已经使用的内存数
free 空闲的内存数
shared 多个进程共享的内存总额
buffers Buffer Cache 和 cached Page Cache 磁盘缓存的大小
-buffers/cache 的内存数: used - buffers - cached
+buffers/cache 的内存数: free + buffers + cached
可用的 memory=free memory+buffers+cached
有了这个基础后, 可以得知, 我现在 used 为 163MB,free 为 86,buffer 和 cached 分别为 10,94
那么我们来看看, 如果我执行复制文件, 内存会发生什么变化.
在我命令执行结束后, used 为 244MB,free 为 4MB,buffers 为 8MB,cached 为 174MB, 天呐都被 cached 吃掉了. 别紧张, 这是为了提高文件读取效率的做法.
为了提高磁盘存取效率, Linux 做了一些精心的设计, 除了对 dentry 进行缓存 (用于 VFS, 加速文件路径名到 inode 的转换), 还采取了两种主要 Cache 方式: Buffer Cache 和 Page Cache. 前者针对磁盘块的读写, 后者针对文件 inode 的读写. 这些 Cache 有效缩短了 I/O 系统调用(比如 read,write,getdents) 的时间."
那么有人说过段时间, linux 会自动释放掉所用的内存, 我们使用 free 再来试试, 看看是否有释放>?
MS 没有任何变化, 那么我能否手动释放掉这些内存呢??? 回答是可以的!
/proc 是一个虚拟文件系统, 我们可以通过对它的读写操作做为与 kernel 实体间进行通信的一种手段. 也就是说可以通过修改 / proc 中的文件, 来对当前 kernel 的行为做出调整. 那么我们可以通过调整 / proc/sys/vm/drop_caches 来释放内存. 操作如下:
[root@server test]# cat /proc/sys/vm/drop_caches
首先,/proc/sys/vm/drop_caches 的值, 默认为 0
[root@server test]# sync
手动执行 sync 命令(描述: sync 命令运行 sync 子例程. 如果必须停止系统, 则运行 sync 命令以确保文件系统的完整性. sync 命令将所有未写的系统缓冲区写到磁盘中, 包含已修改的 i-node, 已延迟的块 I/O 和读写映射文件)
- [root@server test]# echo 3 > /proc/sys/vm/drop_caches
- [root@server test]# cat /proc/sys/vm/drop_caches
将 / proc/sys/vm/drop_caches 值设为 3
再来运行 free 命令, 发现现在的 used 为 66MB,free 为 182MB,buffers 为 0MB,cached 为 11MB. 那么有效的释放了 buffer 和 cache.
有关 / proc/sys/vm/drop_caches 的用法在下面进行了说明
buffer 与 cache 的区别
A buffer is something that has yet to be "written" to disk. A cache is something that has been "read" from the disk and stored for later use.
对于共享内存(Shared memory), 主要用于在 UNIX 环境下不同进程之间共享数据, 是进程间通信的一种方法, 一般的应用程序不会申请使用共享内存, 笔者也没有去验证共享内存对上面等式的影响. 如果你有兴趣, 请参考: What is Shared Memory?
Cache: 高速缓存, 是位于 CPU 与主内存间的一种容量较小但速度很高的存储器. 由于 CPU 的速度远高于主内存, CPU 直接从内存中存取数据要等待一定时间周期, Cache 中保存着 CPU 刚用过或循环使用的一部分数据, 当 CPU 再次使用该部分数据时可从 Cache 中直接调用, 这样就减少了 CPU 的等待时间, 提高了系统的效率. Cache 又分为一级 Cache(L1 Cache)和二级 Cache(L2 Cache),L1 Cache 集成在 CPU 内部, L2 Cache 早期一般是焊在主板上, 现在也都集成在 CPU 内部, 常见的容量有 256KB 或 512KB L2 Cache.
Buffer: 缓冲区, 一个用于存储速度不同步的设备或优先级不同的设备之间传输数据的区域. 通过缓冲区, 可以使进程之间的相互等待变少, 从而使从速度慢的设备读入数据时, 速度快的设备的操作进程不发生间断.
Free 中的 buffer 和 cache:(它们都是占用内存):
buffer : 作为 buffer cache 的内存, 是块设备的读写缓冲区
cache: 作为 page cache 的内存, 文件系统的 cache
如果 cache 的值很大, 说明 cache 住的文件数很多. 如果频繁访问到的文件都能被 cache 住, 那么磁盘的读 IO bi 会非常小.
cache 是高速缓存, 用于 CPU 和内存之间的缓冲;
buffer 是 I/O 缓存, 用于内存和硬盘的缓冲
cache 最初用于 cpu cache, 主要原因是 cpu 与 memory, 由于 cpu 快, memory 跟不上, 且有些值使用次数多, 所以放入. cache 中, 主要目的是, 重复使用, 并且一级二级物理 cache 速度快.
buffer 主要用于 disk 与 memory, 主要是保护硬盘或减少网络传输的次数(内存数据表现 dataSet).当然也可以提高速度(不会立即写入硬盘或直接从硬盘中读出的数据马上显示), 重复使用, 最初最主要的目的是保护 disk.
asp.net 的 cache 有 outputcahe 与数据 cache, 主要目的是 重复使用, 提高速度, outputcache 主要存储 Reader 后的页, 一般是多次使用同一个 html, 建议不要 varybyparam, 不要存多 version, 数据 cache, 如 dataSet, dataTable, 等
@page buffer="true", 使用 buffer, 让 buffer 满后再显示读出或写入,(c 中文件输出也是如此, 主要目的是保护硬盘), 也可以提高下次的访问速度. 在 client browse 端表现是: true 是一次性显示, 要么不显示, 中间等, false 是一次显示一些,
这在网络输出也是如此表现.
对于文件访问 c 中默认采用的是 buffer = true, 这与 asp.net 一样,
相当于 Response.write(); 中当 buffer 满后输出, 以减少网络的传输次数
<%@ OutputCache Duration="60 VaryByParam="none"%>, 是将 asp.net 生成的 HTML 缓存起来, 在指定的时间内不需要重新生成 html, control.ascx. 也有组件缓存(htmlCach). dataSet 也是如此. DataCache,
cache 和 buffer 都是缓冲区, 在翻译上, cache 翻译成高速缓冲区要好一点(因为主要是为下次访问加速), buffer 翻译成缓冲区好点. 都是缓冲的作用, 可目的有点不同, 主要是理解, 不需要太咬文嚼字.
1, Buffer 是缓冲区
2, Cache 是高速缓存, 分 library cache; data dictionary cache; database buffer cache
Buffer cache 缓冲区高速缓存, 用于缓存从硬盘上读取的数据, 减少磁盘 I/O.
3, buffer 有共享 SQL 区和 PL/SQL 区 , 数据库缓冲区高速缓存有独立的 subcache
4, pool 是共享池 用于存储最近执行的语句等
5, cache:A cache is a smaller, higher-speed component that is used to speed up the
access to commonly used data stored in a lower-speed, higher-capacity component. database buffer cache:
The database buffer cache is the portion of the SGA that holds copies of data
blocksread from data files. All user processes concurrently (同时地, 兼任地)connected
to the instance share access to the database buffer cache.
buffer cache 就是以 block 为单位读入写出的.
缓存 (cache) 是把读取过的数据保存起来, 重新读取时若命中 (找到需要的数据) 就不要去读硬盘了, 若没有命中就读硬盘. 其中的数据会根据读取频率进行组织, 把最频繁读取的内容放在最容易找到的位置, 把不再读的内容不断往后排, 直至从中删除.
缓冲 (buffers) 是根据磁盘的读写设计的, 把分散的写操作集中进行, 减少磁盘碎片和硬盘的反复寻道, 从而提高系统性能. linux 有一个守护进程定期清空缓冲内容(即写如磁盘), 也可以通过 sync 命令手动清空缓冲. 举个例子吧:
我这里有一个 ext2 的 U 盘, 我往里面 cp 一个 3M 的 MP3, 但 U 盘的灯没有跳动, 过了一会儿(或者手动输入 sync)U 盘的灯就跳动起来了. 卸载设备时会清空缓冲, 所以有些时候卸载一个设备时要等上几秒钟.
修改 / etc/sysctl.conf 中的 vm.swappiness 右边的数字可以在下次开机时调节 swap 使用策
略. 该数字范围是 0~100, 数字越大越倾向于使用 swap. 默认为 60, 可以改一下试试.
两者都是 RAM 中的数据. 简单来说, buffer 是即将要被写入磁盘的, 而 cache 是被从磁盘中读出来的.
buffer 是由各种进程分配的, 被用在如输入队列等方面, 一个简单的例子如某个进程要求
有多个字段读入, 在所有字段被读入完整之前, 进程把先前读入的字段放在 buffer 中保存
cache 经常被用在磁盘的 I/O 请求上, 如果有多个进程都要访问某个文件, 于是该文件便被
做成 cache 以方便下次被访问, 这样可提供系统性能.
对于共享内存(Shared memory), 主要用于在 UNIX 环境下不同进程之间共享数据, 是进程间通信的一种方法, 一般的应用程序不会申请使用共享内存, 笔者也没有去验证共享内存对上面等式的影响. 如果你有兴趣, 请参考: What is Shared Memory?
- # sync
- # echo 1 > /proc/sys/vm/drop_caches
- echo 2 > /proc/sys/vm/drop_caches
- echo 3 > /proc/sys/vm/drop_caches
cache 释放:
- To free pagecache:
- echo 1 > /proc/sys/vm/drop_caches
- To free dentries and inodes:
- echo 2 > /proc/sys/vm/drop_caches
- To free pagecache, dentries and inodes:
- echo 3 > /proc/sys/vm/drop_caches
说明, 释放前较好 sync 一下, 防止丢数据.
因为 LINUX 的内核机制, 一般情况下不需要特意去释放已经使用的 cache. 这些 cache 起来的内容可以增加文件以及的读写速度.
来源: http://stor.51cto.com/art/201808/580337.htm