Linux内存中的 buffer 和 cache 到底是个什么东东?

  Linux 中的 free 命令,会输出:

  total  总量

  used   已使用

  free  空闲

  shared  共享内存

  buffers  

  cached

  前面四项都比较好理解,一看我也就知道啥意思了。但是buffer 和 cached 我就一直不很理解,终于看到某篇文章写的很详细,于是记下来;

  ·A buffer is something that has yet to be "written" to disk.  ---buffer 写缓存,数据存储时,先保存到磁盘缓冲区,然后再写入到永久空间

  ·A cache is something that has been "reed" from the disk adn stored for later use.   --cache 读缓存,数据从磁盘读出后,暂留在缓冲区,预备程序接下来的使用,

  英文好点的,应该已经看出了端倪,

  buffer 用于存放要输出到磁盘的数据,而cache是从磁盘读出存放到内存中待今后使用的数据。它们的引入均是为了提供IO的性能。

  内存:从用户和操作系统的角度来看,其大小空间是有区别的。像buffer/cached的内存,由于这块内存从操作系统的角度确实被使用,但如果用户要使用,这块内存是可以很快被回收而被用户空间程序使用,因此从用户角度而言这块内存应被划为空闲状态。

  为什么Linux 会有这种机制呢?

  其实这是一种非常优秀的设计,目的就是为了提升磁盘IO的性能,从低速的块设备上读取的数据会暂时保存在内存中,即使数据在当时已经不再需要了,但在应用程序下一次访问该数据时,它可以从内存中直接读取,从而绕开低速的块设备,从而提高系统的整体性能。

在 Linux 系统中,我们经常用 free 命令来查看系统内存的使用状态。在一个 RHEL6 的系统上,free 命令的显示内容大概是这样一个状态:

 
  1. [root@tencent64 ~]# free
  2. total used free shared buffers cached
  3. Mem: 132256952 72571772 59685180 0 1762632 53034704
  4. -/+ buffers/cache: 17774436 114482516
  5. Swap: 2101192 508 2100684

这里的默认显示单位是 kb,我的服务器是 128G 内存,所以数字显得比较大。这个命令几乎是每一个使用过 Linux 的人必会的命令,但越是这样的命令,似乎真正明白的人越少(我是说比例越少)。一般情况下,对此命令输出的理解可以分这几个层次:

  1. 不了解。这样的人的第一反应是:天啊,内存用了好多,70个多 G,可是我几乎没有运行什么大程序啊?为什么会这样? Linux 好占内存!
  2. 自以为很了解。这样的人一般评估过会说:嗯,根据我专业的眼光看的出来,内存才用了 17G 左右,还有很多剩余内存可用。buffers/cache 占用的较多,说明系统中有进程曾经读写过文件,但是不要紧,这部分内存是当空闲来用的。
  3. 真的很了解。这种人的反应反而让人感觉最不懂 Linux,他们的反应是:free 显示的是这样,好吧我知道了。神马?你问我这些内存够不够,我当然不知道啦!我特么怎么知道你程序怎么写的?

根据目前网络上技术文档的内容,我相信绝大多数了解一点 Linux 的人应该处在第二种层次。大家普遍认为,buffers 和 cached 所占用的内存空间是可以在内存压力较大的时候被释放当做空闲空间用的。但真的是这样么?在论证这个题目之前,我们先简要介绍一下 buffers 和 cached 是什么意思:

什么是 buffer/cache?

buffer 和 cache 是两个在计算机技术中被用滥的名词,放在不同语境下会有不同的意义。在 Linux 的内存管理中,这里的buffer 指 Linux 内存的:Buffer cache。这里的 cache 指 Linux 内存中的:Page cache。翻译成中文可以叫做缓冲区缓存页面缓存。在历史上,它们一个(buffer)被用来当成对 io 设备写的缓存,而另一个(cache)被用来当作对 io 设备的读缓存,这里的 io 设备,主要指的是块设备文件和文件系统上的普通文件。但是现在,它们的意义已经不一样了。在当前的内核中,page cache 顾名思义就是针对内存页的缓存,说白了就是,如果有内存是以 page 进行分配管理的,都可以使用 page cache 作为其缓存来管理使用。当然,不是所有的内存都是以页page进行管理的,也有很多是针对块block进行管理的,这部分内存使用如果要用到 cache 功能,则都集中到 buffer cache 中来使用。(从这个角度出发,是不是 buffer cache 改名叫做 block cache 更好?)然而,也不是所有块block都有固定长度,系统上块的长度主要是根据所使用的块设备决定的,而页长度在 X86 上无论是32位还是64位都是 4k。

明白了这两套缓存系统的区别,就可以理解它们究竟都可以用来做什么了。

什么是 page cache

Page cache 主要用来作为文件系统上的文件数据的缓存来用,尤其是针对当进程对文件有 read/write 操作的时候。如果你仔细想想的话,作为可以映射文件到内存的系统调用:mmap 是不是很自然的也应该用到 page cache?在当前的系统实现里, page cache 也被作为其它文件类型的缓存设备来用,所以事实上 page cache 也负责了大部分的块设备文件的缓存工作。

什么是 buffer cache

Buffer cache 则主要是设计用来在系统对块设备进行读写的时候,对块进行数据缓存的系统来使用。这意味着某些对块的操作会使用 buffer cache 进行缓存,比如我们在格式化文件系统的时候。一般情况下两个缓存系统是一起配合使用的,比如当我们对一个文件进行写操作的时候,page cache 的内容会被改变,而 buffer cache 则可以用来将 page 标记为不同的缓冲区,并记录是哪一个缓冲区被修改了。这样,内核在后续执行脏数据的回写writeback时,就不用将整个 page 写回,而只需要写回修改的部分即可。

如何回收 cache?

Linux 内核会在内存将要耗尽的时候,触发内存回收的工作,以便释放出内存给急需内存的进程使用。一般情况下,这个操作中主要的内存释放都来自于对 buffer/cache 的释放。尤其是被使用更多的 cache 空间。既然它主要用来做缓存,只是在内存够用的时候加快进程对文件的读写速度,那么在内存压力较大的情况下,当然有必要清空释放 cache,作为 free 空间分给相关进程使用。所以一般情况下,我们认为 buffer/cache 空间可以被释放,这个理解是正确的。

但是这种清缓存的工作也并不是没有成本。理解 cache 是干什么的就可以明白清缓存必须保证 cache 中的数据跟对应文件中的数据一致,才能对 cache 进行释放。所以伴随着 cache 清除的行为的,一般都是系统 IO 飙高。因为内核要对比 cache 中的数据和对应硬盘文件上的数据是否一致,如果不一致需要写回,之后才能回收。

在系统中除了内存将被耗尽的时候可以清缓存以外,我们还可以使用下面这个文件来人工触发缓存清除的操作:

 
  1. [root@tencent64 ~]# cat /proc/sys/vm/drop_caches
  2. 1

方法是:

 
  1. echo 1 > /proc/sys/vm/drop_caches

当然,这个文件可以设置的值分别为1、2、3。它们所表示的含义为:

echo 1 > /proc/sys/vm/drop_caches:表示清除 page cache。

echo 2 > /proc/sys/vm/drop_caches:表示清除回收 slab 分配器中的对象(包括目录项缓存和 inode 缓存)。slab 分配器是内核中管理内存的一种机制,其中很多缓存数据实现都是用的 page cache。

echo 3 > /proc/sys/vm/drop_caches:表示清除 page cache 和 slab 分配器中的缓存对象。

cache都能被回收么?

我们分析了 cache 能被回收的情况,那么有没有不能被回收的 cache 呢?当然有。我们先来看第一种情况:

tmpfs

大家知道 Linux 提供一种“临时”文件系统叫做 tmpfs,它可以将内存的一部分空间拿来当做文件系统使用,使内存空间可以当做目录文件来用。现在绝大多数 Linux 系统都有一个叫做 /dev/shm 的 tmpfs 目录,就是这样一种存在。当然,我们也可以手工创建一个自己的 tmpfs,方法如下:

 
  1. [root@tencent64 ~]# mkdir /tmp/tmpfs
  2. [root@tencent64 ~]# mount -t tmpfs -o size=20G none /tmp/tmpfs/
  3. [root@tencent64 ~]# df
  4. Filesystem 1K-blocks Used Available Use% Mounted on
  5. /dev/sda1 10325000 3529604 6270916 37% /
  6. /dev/sda3 20646064 9595940 10001360 49% /usr/local
  7. /dev/mapper/vg-data 103212320 26244284 71725156 27% /data
  8. tmpfs 66128476 14709004 51419472 23% /dev/shm
  9. none 20971520 0 20971520 0% /tmp/tmpfs

于是我们就创建了一个新的 tmpfs,空间是 20G,我们可以在 /tmp/tmpfs 中创建一个 20G 以内的文件。如果我们创建的文件实际占用的空间是内存的话,那么这些数据应该占用内存空间的什么部分呢?根据 page cache 的实现功能可以理解,既然是某种文件系统,那么自然该使用 page cache 的空间来管理。我们试试是不是这样?

 
  1. [root@tencent64 ~]# free -g
  2. total used free shared buffers cached
  3. Mem: 126 36 89 0 1 19
  4. -/+ buffers/cache: 15 111
  5. Swap: 2 0 2
  6. [root@tencent64 ~]# dd if=/dev/zero of=/tmp/tmpfs/testfile bs=1G count=13
  7. 13+0 records in
  8. 13+0 records out
  9. 13958643712 bytes (14 GB) copied, 9.49858 s, 1.5 GB/s
  10. [root@tencent64 ~]#
  11. [root@tencent64 ~]# free -g
  12. total used free shared buffers cached
  13. Mem: 126 49 76 0 1 32
  14. -/+ buffers/cache: 15 110
  15. Swap: 2 0 2

我们在 tmpfs 目录下创建了一个 13G 的文件,并通过前后 free 命令的对比发现,cached 增长了 13G,说明这个文件确实放在了内存里并且内核使用的是 cache 作为存储。再看看我们关心的指标: -/+ buffers/cache 那一行。我们发现,在这种情况下 free 命令仍然提示我们有 110G 内存可用,但是真的有这么多么?我们可以人工触发内存回收看看现在到底能回收多少内存:

 
  1. [root@tencent64 ~]# echo 3 > /proc/sys/vm/drop_caches
  2. [root@tencent64 ~]# free -g
  3. total used free shared buffers cached
  4. Mem: 126 43 82 0 0 29
  5. -/+ buffers/cache: 14 111
  6. Swap: 2 0 2

可以看到,cached 占用的空间并没有像我们想象的那样完全被释放,其中 13G 的空间仍然被 /tmp/tmpfs 中的文件占用的。当然,我的系统中还有其他不可释放的 cache 占用着其余16G内存空间。那么 tmpfs 占用的 cache 空间什么时候会被释放呢?是在其文件被删除的时候。如果不删除文件,无论内存耗尽到什么程度,内核都不会自动帮你把 tmpfs 中的文件删除来释放cache空间。

 
  1. [root@tencent64 ~]# rm /tmp/tmpfs/testfile
  2. [root@tencent64 ~]# free -g
  3. total used free shared buffers cached
  4. Mem: 126 30 95 0 0 16
  5. -/+ buffers/cache: 14 111
  6. Swap: 2 0 2

这是我们分析的第一种 cache 不能被回收的情况。还有其他情况,比如:

共享内存

共享内存是系统提供给我们的一种常用的进程间通信(IPC)方式,但是这种通信方式不能在 shell 中申请和使用,所以我们需要一个简单的测试程序,代码如下:

 
  1. [root@tencent64 ~]# cat shm.c
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <unistd.h>
  5. #include <sys/ipc.h>
  6. #include <sys/shm.h>
  7. #include <string.h>
  8. #define MEMSIZE 2048*1024*1023
  9. int
  10. main()
  11. {
  12. int shmid;
  13. char *ptr;
  14. pid_t pid;
  15. struct shmid_ds buf;
  16. int ret;
  17. shmid = shmget(IPC_PRIVATE, MEMSIZE, 0600);
  18. if (shmid<0) {
  19. perror("shmget()");
  20. exit(1);
  21. }
  22. ret = shmctl(shmid, IPC_STAT, &buf);
  23. if (ret < 0) {
  24. perror("shmctl()");
  25. exit(1);
  26. }
  27. printf("shmid: %d\n", shmid);
  28. printf("shmsize: %d\n", buf.shm_segsz);
  29. buf.shm_segsz *= 2;
  30. ret = shmctl(shmid, IPC_SET, &buf);
  31. if (ret < 0) {
  32. perror("shmctl()");
  33. exit(1);
  34. }
  35. ret = shmctl(shmid, IPC_SET, &buf);
  36. if (ret < 0) {
  37. perror("shmctl()");
  38. exit(1);
  39. }
  40. printf("shmid: %d\n", shmid);
  41. printf("shmsize: %d\n", buf.shm_segsz);
  42. pid = fork();
  43. if (pid<0) {
  44. perror("fork()");
  45. exit(1);
  46. }
  47. if (pid==0) {
  48. ptr = shmat(shmid, NULL, 0);
  49. if (ptr==(void*)-1) {
  50. perror("shmat()");
  51. exit(1);
  52. }
  53. bzero(ptr, MEMSIZE);
  54. strcpy(ptr, "Hello!");
  55. exit(0);
  56. } else {
  57. wait(NULL);
  58. ptr = shmat(shmid, NULL, 0);
  59. if (ptr==(void*)-1) {
  60. perror("shmat()");
  61. exit(1);
  62. }
  63. puts(ptr);
  64. exit(0);
  65. }
  66. }

程序功能很简单,就是申请一段不到 2G 共享内存,然后打开一个子进程对这段共享内存做一个初始化操作,父进程等子进程初始化完之后输出一下共享内存的内容,然后退出。但是退出之前并没有删除这段共享内存。我们来看看这个程序执行前后的内存使用:

 
  1. [root@tencent64 ~]# free -g
  2. total used free shared buffers cached
  3. Mem: 126 30 95 0 0 16
  4. -/+ buffers/cache: 14 111
  5. Swap: 2 0 2
  6. [root@tencent64 ~]# ./shm
  7. shmid: 294918
  8. shmsize: 2145386496
  9. shmid: 294918
  10. shmsize: -4194304
  11. Hello!
  12. [root@tencent64 ~]# free -g
  13. total used free shared buffers cached
  14. Mem: 126 32 93 0 0 18
  15. -/+ buffers/cache: 14 111
  16. Swap: 2 0 2

cached 空间由 16G 涨到了 18G。那么这段 cache 能被回收么?继续测试:

 
  1. [root@tencent64 ~]# echo 3 > /proc/sys/vm/drop_caches
  2. [root@tencent64 ~]# free -g
  3. total used free shared buffers cached
  4. Mem: 126 32 93 0 0 18
  5. -/+ buffers/cache: 14 111
  6. Swap: 2 0 2

结果是仍然不可回收。大家可以观察到,这段共享内存即使没人使用,仍然会长期存放在 cache 中,直到其被删除。删除方法有两种,一种是程序中使用 shmctl() 去 IPC_RMID,另一种是使用 ipcrm 命令。我们来删除试试:

 
  1. [root@tencent64 ~]# ipcs -m
  2. ------ Shared Memory Segments --------
  3. key shmid owner perms bytes nattch status
  4. 0x00005feb 0 root 666 12000 4
  5. 0x00005fe7 32769 root 666 524288 2
  6. 0x00005fe8 65538 root 666 2097152 2
  7. 0x00038c0e 131075 root 777 2072 1
  8. 0x00038c14 163844 root 777 5603392 0
  9. 0x00038c09 196613 root 777 221248 0
  10. 0x00000000 294918 root 600 2145386496 0
  11. [root@tencent64 ~]# ipcrm -m 294918
  12. [root@tencent64 ~]# ipcs -m
  13. ------ Shared Memory Segments --------
  14. key shmid owner perms bytes nattch status
  15. 0x00005feb 0 root 666 12000 4
  16. 0x00005fe7 32769 root 666 524288 2
  17. 0x00005fe8 65538 root 666 2097152 2
  18. 0x00038c0e 131075 root 777 2072 1
  19. 0x00038c14 163844 root 777 5603392 0
  20. 0x00038c09 196613 root 777 221248 0
  21. [root@tencent64 ~]# free -g
  22. total used free shared buffers cached
  23. Mem: 126 30 95 0 0 16
  24. -/+ buffers/cache: 14 111
  25. Swap: 2 0 2

删除共享内存后,cache 被正常释放了。这个行为与 tmpfs 的逻辑类似。内核底层在实现共享内存(shm)、消息队列(msg)和信号量数组(sem)这些 POSIX:XSI 的 IPC 机制的内存存储时,使用的都是 tmpfs。这也是为什么共享内存的操作逻辑与 tmpfs 类似的原因。当然,一般情况下是 shm 占用的内存更多,所以我们在此重点强调共享内存的使用。说到共享内存,Linux 还给我们提供了另外一种共享内存的方法,就是:

mmap

mmap() 是一个非常重要的系统调用,这仅从 mmap 本身的功能描述上是看不出来的。从字面上看,mmap 就是将一个文件映射进进程的虚拟内存地址,之后就可以通过操作内存的方式对文件的内容进行操作。但是实际上这个调用的用途是很广泛的。当 malloc 申请内存时,小段内存内核使用 sbrk 处理,而大段内存就会使用 mmap。当系统调用 exec 族函数执行时,因为其本质上是将一个可执行文件加载到内存执行,所以内核很自然的就可以使用 mmap 方式进行处理。我们在此仅仅考虑一种情况,就是使用 mmap 进行共享内存的申请时,会不会跟 shmget() 一样也使用 cache?

同样,我们也需要一个简单的测试程序:

 
  1. [root@tencent64 ~]# cat mmap.c
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <strings.h>
  5. #include <sys/mman.h>
  6. #include <sys/stat.h>
  7. #include <sys/types.h>
  8. #include <fcntl.h>
  9. #include <unistd.h>
  10. #define MEMSIZE 1024*1024*1023*2
  11. #define MPFILE "./mmapfile"
  12. int main()
  13. {
  14. void *ptr;
  15. int fd;
  16. fd = open(MPFILE, O_RDWR);
  17. if (fd < 0) {
  18. perror("open()");
  19. exit(1);
  20. }
  21. ptr = mmap(NULL, MEMSIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANON, fd, 0);
  22. if (ptr == NULL) {
  23. perror("malloc()");
  24. exit(1);
  25. }
  26. printf("%p\n", ptr);
  27. bzero(ptr, MEMSIZE);
  28. sleep(100);
  29. munmap(ptr, MEMSIZE);
  30. close(fd);
  31. exit(1);
  32. }

这次我们干脆不用什么父子进程的方式了,就一个进程,申请一段 2G 的 mmap 共享内存,然后初始化这段空间之后等待 100 秒,再解除影射所以我们需要在它 sleep 这 100 秒内检查我们的系统内存使用,看看它用的是什么空间?当然在这之前要先创建一个 2G 的文件 ./mmapfile。结果如下:

 
  1. [root@tencent64 ~]# dd if=/dev/zero of=mmapfile bs=1G count=2
  2. [root@tencent64 ~]# echo 3 > /proc/sys/vm/drop_caches
  3. [root@tencent64 ~]# free -g
  4. total used free shared buffers cached
  5. Mem: 126 30 95 0 0 16
  6. -/+ buffers/cache: 14 111
  7. Swap: 2 0 2

然后执行测试程序:

 
  1. [root@tencent64 ~]# ./mmap &
  2. [1] 19157
  3. 0x7f1ae3635000
  4. [root@tencent64 ~]# free -g
  5. total used free shared buffers cached
  6. Mem: 126 32 93 0 0 18
  7. -/+ buffers/cache: 14 111
  8. Swap: 2 0 2
  9. [root@tencent64 ~]# echo 3 > /proc/sys/vm/drop_caches
  10. [root@tencent64 ~]# free -g
  11. total used free shared buffers cached
  12. Mem: 126 32 93 0 0 18
  13. -/+ buffers/cache: 14 111
  14. Swap: 2 0 2

我们可以看到,在程序执行期间,cached 一直为 18G,比之前涨了 2G,并且此时这段 cache 仍然无法被回收。然后我们等待100秒之后程序结束。

 
  1. [root@tencent64 ~]#
  2. [1]+ Exit 1 ./mmap
  3. [root@tencent64 ~]#
  4. [root@tencent64 ~]# free -g
  5. total used free shared buffers cached
  6. Mem: 126 30 95 0 0 16
  7. -/+ buffers/cache: 14 111
  8. Swap: 2 0 2

程序退出之后,cached 占用的空间被释放。这样我们可以看到,使用 mmap 申请标志状态为 MAP_SHARED 的内存,内核也是使用的 cache 进行存储的。在进程对相关内存没有释放之前,这段 cache 也是不能被正常释放的。实际上,mmap 的 MAP_SHARED 方式申请的内存,在内核中也是由 tmpfs 实现的。由此我们也可以推测,由于共享库的只读部分在内存中都是以 mmap 的 MAP_SHARED 方式进行管理,实际上它们也都是要占用 cache 且无法被释放的。

最后

我们通过三个测试例子,发现 Linux 系统内存中的 cache 并不是在所有情况下都能被释放当做空闲空间用的。并且也也明确了,即使可以释放 cache,也并不是对系统来说没有成本的。总结一下要点,我们应该记得这样几点:

  1. 当 cache 作为文件缓存被释放的时候会引发 IO 变高,这是 cache 加快文件访问速度所要付出的成本。
  2. tmpfs 中存储的文件会占用 cache 空间,除非文件删除否则这个 cache 不会被自动释放。
  3. 使用 shmget 方式申请的共享内存会占用 cache 空间,除非共享内存被 ipcrm 或者使用 shmctl 去 IPC_RMID,否则相关的 cache 空间都不会被自动释放。
  4. 使用 mmap 方法申请的 MAP_SHARED 标志的内存会占用 cache 空间,除非进程将这段内存 munmap,否则相关的 cache 空间都不会被自动释放。
  5. 实际上 shmget、mmap 的共享内存,在内核层都是通过 tmpfs 实现的,tmpfs 实现的存储用的都是 cache。

当理解了这些的时候,希望大家对 free 命令的理解可以达到我们说的第三个层次。我们应该明白,内存的使用并不是简单的概念,cache 也并不是真的可以当成空闲空间用的。如果我们要真正深刻理解你的系统上的内存到底使用的是否合理,是需要理解清楚很多更细节知识,并且对相关业务的实现做更细节判断的。我们当前实验场景是 Centos 6 的环境,不同版本的 Linux 的 free 现实的状态可能不一样,大家可以自己去找出不同的原因。

当然,本文所述的也不是所有的 cache 不能被释放的情形。那么,在你的应用场景下,还有那些 cache 不能被释放的场景呢?

Linux内存中的 buffer 和 cache相关推荐

  1. Linux内存中的 buffer 和 cache 到底是个什么东东?

    Linux 中的 free 命令,会输出: total 总量 used  已使用 free 空闲 shared 共享内存 buffers cached 前面四项都比较好理解,一看我也就知道啥意思了.但 ...

  2. 怎么理解内存中的Buffer和Cache

    本文是通过学习倪朋飞老师的<Linux性能优化实战> :怎么理解内存中的Buffer和Cache? 怎么理解内存中的Buffer和Cache? free 数据的来源 proc 文件系统 案 ...

  3. linux buffer cache 过高_怎么理解内存中的Buffer和Cache?

    1|0缓存 从 free 命令可以看到,缓存其实就是 Buffer 和 Cache 两部分的总和 字面意思,Buffer 是缓存区,Cache 是缓存,两者都是数据再内存中的临时存储 2|0Buffe ...

  4. 16 | 基础篇:怎么理解内存中的Buffer和Cache?

    上一节,我们梳理了 Linux 内存管理的基本原理,并学会了用 free 和 top 等工具,来查看系统和进程的内存使用情况. 在今天的内容开始之前,我们先来回顾一下系统的内存使用情况,比如下面这个 ...

  5. 内存中的Buffer和Cache

    这个界面包含了物理内存Mem和交换分区Swap的使用情况,其中包括以用内存.缓存.可用内存等.其中缓存是buffer和cache这两部分的总和. 从字面意思理解,Buffer和Cache分别代表缓冲区 ...

  6. Linux 内存中的Cache

    您真的了解Linux的free命令么? Linux上的free命令详解 解释一下Linux上free命令的输出. 下面是free的运行结果,一共有4行.为了方便说明,我加上了列号.这样可以把free的 ...

  7. Linux内存中的Cache真的能被回收么?

    官方网站 www.itilzj.com 资料文档: wenku.itilzj.com  前言 在Linux系统中,我们经常用free命令来查看系统内存的使用状态.在一个RHEL6的系统上,free命令 ...

  8. Linux 内存中的缓冲区(Buffer)与缓存(Cache)

    Buffer 和 Cache 的定义: Buffer:是原始磁盘块的临时存储,即将缓存数据写入磁盘.它通常不会很大(大约  20MB).这样,内核就可以将分散的写入集中起来,从而对磁盘写入进行统一优化 ...

  9. 宋宝华:linux内存中 swappiness=0究竟意味着什么?

    本文解释linux内存中swappiness的作用,以及linux内存中swappiness=0究竟意味着什么. 内存回收 我们都知道,Linux一个进程使用的内存分为2种: file-backed ...

最新文章

  1. MATLAB可以打开gms文件吗,GMS文件扩展名 - 什么是.gms以及如何打开? - ReviverSoft...
  2. 芝麻HTTP:Scrapy-Splash的安装
  3. C++添加程序到windows的启动项的代码
  4. SharePoint 2007 文件夹或者文件名过长
  5. AMD发布“全球单核性能最快”CPU,参数碾压英特尔,性能提升47%
  6. Springboot 2.返回cookies信息的get接口开发 和 带cookis去请求
  7. 分布式单点登录框架XXL-SSO
  8. Linux下克隆的修改IP
  9. Android Build.VERSION.SDK_INT兼容介绍
  10. java内存stack heap_java内存解析-------stack(栈)和heap(堆)的理解
  11. Java学习之字符与ASCII码相互转换的面板设计
  12. vue+express+mongoose项目构建
  13. 很简单的源码剖析-SpringBoot内嵌Tomcat原理
  14. AI数据服务行业进入“认知战争”,云测数据凭什么稳居行业TOP1?
  15. JAVA SE 基础汇总
  16. 地图图像迁移研究与实现
  17. JAVA 日期推算---算法
  18. 内网渗透(十七)之内网信息收集-powershell收集域内信息和敏感数据定位
  19. 小程序开发(一)新建/拉取项目,配置远程仓库
  20. 《程序员修炼之道——从小工到专家》读后感一

热门文章

  1. 文件系统与NoSQL分布式存储技术对比
  2. oracle表行列权限,Oracle行列互换 横表和纵表
  3. php yield 递归,递归运行所有yield请求h的废弃输出文件
  4. java执行器是什么_java使用Executor(执行器)管理线程
  5. websocket创建失败_SpringBoot2.2 实践WebSocket被不靠谱的百度搜索结果坑了多少人
  6. bose耳机信号断续_最便宜的TWS主动降噪耳机 233621 Zen 4400字深度评测
  7. java stringbu,Java String和StringBuilder常用方法,
  8. python随机生成一个地区地址_为特定地区/国家生成随机坐标的轻量级工具?
  9. python 调用摄像头拍照_《自拍教程67》Python调用摄像头, 拍照拍照!
  10. java8编译_为什么在Java7中编译而在Java8中编译?