Linux内存--虚拟内存,buffer/cache

Linux内存相关

在这里插入图片描述
上图是32位的操作系统的地址空间情况。

申请虚拟内存

首先获取寻址大小:查看cat /proc/cpuinfo

yms@ubuntu:~$ cat /proc/cpuinfo
processor       : 0
vendor_id       : GenuineIntel
cpu family      : 6
model           : 79
model name      : Intel(R) Xeon(R) CPU E5-2620 v4 @ 2.10GHz
stepping        : 1
microcode       : 0xb00002c
cpu MHz         : 2100.000
cache size      : 20480 KB
physical id     : 0
siblings        : 16
core id         : 0
cpu cores       : 8
apicid          : 0
initial apicid  : 0
fpu             : yes
fpu_exception   : yes
cpuid level     : 20
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch epb invpcid_single intel_pt ibrs ibpb stibp kaiser tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm cqm rdseed adx smap xsaveopt cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local dtherm arat pln pts
bugs            : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass
bogomips        : 4190.67
clflush size    : 64
cache_alignment : 64
address sizes   : 46 bits physical, 48 bits virtual
power management:

由上图可知:

address sizes : 46 bits physical, 48 bits virtual
48位虚拟地址空间,所以可寻址范围2^48, 内核空间和用户空间各占一半;所以用户空间可连续malloc的大小为(2^48)/2 = 2^47 = 2^10 * 2^10 * 2^10 * 2^17

那么我们通过一个例子来进行验证(使用malloc进行虚拟地址的申请,看我们最多能申请多少大小的空间):
测试代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main()
{

    unsigned long long mem_size = (unsigned long long)(1024*1024*1024)*1;//1G
    printf("mem_size: %llu\n",mem_size);

    int i = 0;
    while(1) {
        i++;
        int* p_malloc;
        p_malloc = (int*)malloc(mem_size);
        printf("p_malloc: %p\n",p_malloc);
        printf("i: %d\n", i);

    }
    return 0;
}

yms@ubuntu:~/sunrise/C++/memory_demo$ gcc main_virtual_address.c -o virtual_address
yms@ubuntu:~/sunrise/C++/memory_demo$ ./virtual_address

i: 131070
p_malloc: 0x7fff681fb010
*p_malloc: 0
i: 131071
p_malloc: 0x7fffa821c010
*p_malloc: 0
i: 131072
p_malloc: (nil)
Segmentation fault (core dumped)

可以看到当malloc申请到131072G的时候,malloc出错(超过了可申请的范围);2^17 = 131072
得到总结:
1、malloc是申请连续的虚拟地址空间。
2、虚拟地址可申请的空间,由虚拟地址可寻址范围确认(48 bits virtual)。
3、malloc只是申请虚拟地址空间,并没有真正的使用到物理内存,需要memset才会真正和物理内存建立真正的映射。

buffer/cache

在这里插入图片描述
在这里插入图片描述
进程读写磁盘文件,会使该区域增加;
app <-> buffer/cache <-> disk
应用读取文件:
先读取cache区域,若存在,则返回,若不存在,则直接读取disk内容(同时将内容缓存到cache区域)
应用写文件:
将内容写入buffer,后台线程定时去将buffer回写到disk。

缓存机制优点:减少系统调用次数,降低CPU上下文切换和磁盘访问频率。
缓存(cached)是把读取过的数据保存起来,重新读取时若命中(找到需要的数据)就不要去读硬盘了,若没有命中就读硬盘。其中的数据会根据读取频率进行组织,把最频繁读取的内容放在最容易找到的位置,把不再读的内容不断往后排,直至从中删除。
缓冲(buffers)是根据磁盘的读写设计的,把分散的写操作集中进行,减少磁盘碎片和硬盘的反复寻道,从而提高系统性能。linux有一个守护进程定期清空缓冲内容(即写入磁盘),也可以通过sync命令手动清空缓冲。举个例子吧:我这里有一个ext2的U盘,我往里面cp一个3M的MP3,但U盘的灯没有跳动,过了一会儿(或者手动输入sync)U盘的灯就跳动起来了。卸载设备时会清空缓冲,所以有些时候卸载一个设备时要等上几秒钟。

读取文件

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
    char buf_r[1024];
    int size;
    int fd = open("/home/yms/test/mdc_syslog0.log",O_RDWR);// 该文件为960M,运行完该程序,buffer/cache大小会增加960M
    if (fd == -1) {
        printf("error open file");
    }else {
        while ((size = read( fd, buf_r, 1024))>0) { // 读取普通文件,首次运行,从磁盘中获取,并将其写入到cache中,再次读取时,则从cache中读取
            printf("read form file:%s OK\n",buf_r);
        }
    }
    close(fd);

    while(1) {
    }

    return 0;
}

编译及运行

gcc buffer_cache_demo.c -o buffer_cache_demo
./buffer_cache_demo

运行的同时,查看内存占用(top 或者 free)
top信息(运行前):

top - 06:35:46 up 52 days, 3:39, 48 users, load average: 0.00, 0.07, 0.07
Tasks: 582 total, 1 running, 456 sleeping, 121 stopped, 4 zombie
%Cpu(s): 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 128541.3+total, 127718.5+free, 539.234 used, 283.520 buff/cache
MiB Swap: 1950.992 total, 1132.133 free, 818.859 used. 127381.5+avail Mem

运行后

top - 06:44:10 up 52 days, 3:48, 48 users, load average: 1.04, 0.64, 0.31
Tasks: 582 total, 2 running, 455 sleeping, 121 stopped, 4 zombie
%Cpu(s): 3.1 us, 0.0 sy, 0.0 ni, 96.8 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 128541.3+total, 126775.3+free, 539.242 used, 1226.777 buff/cache
MiB Swap: 1950.992 total, 1132.219 free, 818.773 used. 127291.9+avail Mem

再次运行:

top - 06:49:07 up 52 days, 3:53, 48 users, load average: 0.44, 0.47, 0.33
Tasks: 584 total, 2 running, 457 sleeping, 121 stopped, 4 zombie
%Cpu(s): 3.1 us, 0.0 sy, 0.0 ni, 96.8 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 128541.3+total, 126775.7+free, 538.625 used, 1226.984 buff/cache
MiB Swap: 1950.992 total, 1132.285 free, 818.707 used. 127292.4+avail Mem

手动清除缓存:

释放缓存区内存的方法
1)清理pagecache(页面缓存)
[root@backup ~]# echo 1 > /proc/sys/vm/drop_caches 或者 # sysctl -w vm.drop_caches=1

2)清理dentries(目录缓存)和inodes
[root@backup ~]# echo 2 > /proc/sys/vm/drop_caches 或者 # sysctl -w vm.drop_caches=2

3)清理pagecache、dentries和inodes
[root@backup ~]# echo 3 > /proc/sys/vm/drop_caches 或者 # sysctl -w vm.drop_caches=3

上面三种方式都是临时释放缓存的方法,要想永久释放缓存,需要在/etc/sysctl.conf文件中配置:vm.drop_caches=1/2/3,然后sysctl -p生效即可!

手动执行完上面三个清除动作后的top信息

top - 06:50:43 up 52 days, 3:54, 48 users, load average: 0.69, 0.58, 0.39
Tasks: 584 total, 1 running, 458 sleeping, 121 stopped, 4 zombie
%Cpu(s): 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 128541.3+total, 127723.4+free, 541.965 used, 275.934 buff/cache
MiB Swap: 1950.992 total, 1132.305 free, 818.688 used. 127382.3+avail Mem

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux内存buffer/cache很大是因为Linux系统采用了一种称为页缓存(Page Cache)的机制来提高文件系统的性能。具体来说,当文件被读取到内存中时,Linux会将读取到的文件数据缓存到内存的页缓存中,以便下次访问相同文件时可以直接从页缓存中获取,而不需要再次从磁盘中读取。这种机制可以大大提升系统IO的性能。 Linux内存buffer/cache的大小受到系统资源管理的影响,它会充分利用可用的内存空间来提供更高效的文件访问。当系统运行时,如果有大量的可用内存,并且没有其他进程需要使用,Linux会将这些多余的内存用于buffer/cache。这样一来,当需要从磁盘读取文件时,大部分情况下可以直接从内存中获取,而不必再次访问磁盘,从而大大提高系统的响应速度。 值得注意的是,虽然buffer/cache占用了大量内存,但这些内存并不是完全被占用,而是可以根据需要被释放的。当其他程序需要更多的内存时,Linux会自动将buffer/cache中的数据释放出来,以满足其他程序的需求。这个过程被称为自动缓存(Automatic caching),可以确保系统内存始终处于最佳状态。 总而言之,Linux内存buffer/cache很大是Linux系统为了提高文件系统的性能而采取的一种机制。通过将文件数据缓存到内存中,可以减少对磁盘的读取操作,从而大大提升了系统的响应速度。同时,这些内存可以根据需要进行释放,确保系统内存始终处于最佳状态。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值