释放内存有三种方法(官方有解释)

面试中发现大量的人对这块几乎是空白,谁都知道free -m  但是究竟什么意思,都说的不是很清楚了。 因为网上很多写的也不是很详细。或者本身就有误区
我这块也是在不断调整阐述的内容和方式以及样式。出了多个版本,力求更好的进行解释呈现。


系统采样

[root@fp-web-112 ~]# cat /etc/redhat-release 
CentOS Linux release 7.2.1511 (Core) 


查看机器内存占用情况

 我们简单解释一下输出的信息:
1、总的内存15G
2、已经使用将近1个G
3、buff数据即等待写入设备的数据+磁盘读取出来放在cache中提高访问速度的加起来是11G
     这部分属于临时的,我们可以在内存遇到瓶颈的时候,想办法释放出来的。
    buffer是用于存放要写入到磁盘或者其他块设备的数据,cache是存放从磁盘或其他文件系统上读出的数据。这二者是为了提高IO性能的,并由OS管理。
    我们狭义的理解:在历史上,它们一个(buffer)被用来当成对io设备写的缓存,而另一个(cache)被用来当作对io设备的读缓存,
    这里的io设备,主要指的是块设备文件和文件系统上的普通文件。我们如果深入了解过linux或读过操作系统原理就知道linux内存管理方式是.
4、cache这里实际就是page cache(系统内核层面就叫page cache,这是linux内存页管理机制,page cache跟磁盘io密切相关)
   它的具体大小,我们是可以通过/proc/meminfo来查看的,本身free命令也是读取的/proc/meminfo数据提取的.
5、free列表示可用3.2G,因为buff+cache占用了11G
6、swap空间 也交换空间,linux根据自己的算法把暂时不用的内存块数据,放到这里来.

如果你的内存存在问题,你也最好用slabtop也查看下内核占用内存情况,往往slab占用的缓存也不是不少的(slab+buddy是linux内存管理机制)

 

上面的输出中内存计算公式

 MemTotal = MemFree +【Slab+ VmallocUsed + PageTables + KernelStack + HardwareCorrupted + Bounce + X】+【Active + Inactive + Unevictable + (HugePages_Total * Hugepagesize)】
MemTotal = MemFree +【Slab+ VmallocUsed + PageTables + KernelStack + HardwareCorrupted + Bounce + X】+【Cached + AnonPages + Buffers + (HugePages_Total * Hugepagesize)】
MemTotal = MemFree +【Slab+ VmallocUsed + PageTables + KernelStack + HardwareCorrupted + Bounce + X】+【ΣPss + (Cached – mapped) + Buffers + (HugePages_Total * Hugepagesize)】

 

为了提高磁盘存取效率, 除了对dentry进行缓存(用于VFS,加速文件路径名到inode的转换),还采取了两种主要Cache方式:Buffer Cache和Page Cache。
前者针对磁盘块的读写,后者针对文件inode的读写。

dentry解释:dentry是一个纯粹的内存结构,由文件系统在提供文件访问的过程中在内存中直接建立,dentry,即directory entry,目录项,就是多个文件或者目录的链接,通过这个链接可以找寻到目录之下的文件或者是目录项。dentry在文件系统里是极其重要的一个概念,dentry结构体在linux内核里也是用处广泛,这个结构体定义在include/linux/dcache.h里。

这些Cache有效缩短了 I/O系统调用(比如read,write,getdents)的时间。

inode仅仅只是保存了文件对象的属性信息,包括:权限、属组、数据块的位置、时间戳等信息。但是并没有包含文件名,文件在文件系统的目录树中所处的位置信息。那么内核又是怎么管理文件系统的目录树呢?答案是目录项。目录项在内核中起到了连接不同的文件对象inode的作用,进而起到了维护文件系统目录树的作用。 

关于inode可以看我的另一篇 https://www.cnblogs.com/aozhejin/p/15873245.html

 

内存信息文件位置在/proc/meminfo中,该文件记录内存的实时信息。/proc/meminfo是了解Linux系统内存使用状况的主要接口
平常使用的“free", "vmstat"等命令都是通过这个文件获取数据的。
我们知道 /proc目录是linux中的虚拟文件目录,记录着内核中实时相关的数据以及进程的相关信息,通过这个目录下的文件修改,可以干预linux的行为
所以另外章节说明一下/proc 这里面的内容.
可参考内核官方解释:  https://www.kernel.org/doc/Documentation/filesystems/proc.txt   //这个可能需要你掌握比较多的系统原理性内容以及英语。

我们查看/proc/meminfo 这个文件的内容同时做一些注解,但是要注意Linux 内核并没有统计到所有的内存分配,
内核动态分配的内存中就有一部分没有计入/proc/meminfo中。

[root@fp-web-112 ~]# cat /proc/meminfo

MemTotal: 16418116 kB  //系统从加电开始到引导完成,firmware/BIOS要保留一些内存,kernel本身要占用一些内存,最后剩下可供kernel支配的内存就是MemTotal
MemFree: 1717744 kB //表示系统尚未使用的内存,但是MemFree不能代表全部可用的内存,系统中有些内存虽然已被使用但是可以回收的,
比如cache/buffer、slab都有一部分可以回收,所以这部分可回收的内存加上MemFree才是系统可用的内存。
MemAvailable: 15052664 kB    //是内核使用特定的算法估算出来的,要注意这是一个估计值,并不精确
Buffers: 2772 kB          //缓冲区使用的内存,临时存储原始磁盘块的总量
Cached: 13101368 kB          //文件缓存页
SwapCached: 0 kB           //交换分区内存,这个需要开启swap.
Active: 12044148 kB        //最近经常被使用的内存大小总量(包括文件页缓存和匿名页缓存), 我们使用的vmstat -a 命令也是读取的这个文件中的这个项。
Inactive: 1829524 kB        //最近不是经常使用的内存(可以被释放的pagecache memory)
Active(anon): 769896 kB      //匿名和tmpfs/shmem内存总量
Inactive(anon): 852 kB       //不活跃的匿名页缓存
Active(file): 11274252 kB    //活跃的文件页缓存,
Inactive(file): 1828672 kB   //不活跃的文件页缓存
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 39145464 kB   //交换空间总的大小
SwapFree: 39145464 kB    //空闲的交换空间
Dirty: 980 kB            //需要写入磁盘缓存数据(一般叫磁盘写缓冲),980k即占用的内存大小,如果很多,可以使用 sync 同步一下也就是写入磁盘,释放写缓冲
Writeback: 0 kB          //正在被写回的内存区的大小
AnonPages: 769536 kB
Mapped: 177700 kB
Shmem: 1212 kB
Slab: 564860 kB          //slab缓存大小,这个大小有时候不可以忽略,需要关注。slab分配的内存会被精确统计 (可以使用slabtop查看linux内核的数据结构对象的缓存情况)
SReclaimable: 485412 kB  //SReclaimable指可收回Slab的大小(slab就是内核缓存,可查看 /proc/slabinfo)
SUnreclaim: 79448 kB     
//slab不可回收部分(2.6.2之后linux引入的内存管理机器,我们通过用buddy分配内存是以4k为单位(4k是否看系统,一般都是4k),
但是也有一些几k或几百字节的数据结构要存储,所以slab就很好的解决了这个问题)
KernelStack: 11312 kB
PageTables: 10580 kB   //管理内存分页的索引表的大小(页表数量)
NFS_Unstable: 0 kB     //NFS_Unstable是发给NFS server但尚未写入硬盘的缓存页
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 47354520 kB
Committed_AS: 2404288 kB
VmallocTotal: 34359738367 kB   //通过vmalloc分配的内存(以字节为单位分配虚拟地址连续的内存块),该内存属于内核动态内存的内存
VmallocUsed: 218620 kB         //kernel module的内存被包含在VmallocUsed中
VmallocChunk: 34359409616 kB
HardwareCorrupted: 0 kB
AnonHugePages: 112640 kB
HugePages_Total: 0        //大页总的数量,如果你的linux设置了大页模式。当前的page页大小可以通过 getconf PAGE_SIZE 命令得到,一般是4092/1024=4k
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
DirectMap 4k: 116544 kB     //表示映射为4kB的内存数量
DirectMap 2M: 4077568 kB    //示映射为2MB的内存数量,DirectMap所统计的不是关于内存的使用,而是一个反映TLB效率的指标。
TLB(Translation Lookaside Buffer)是位于CPU上的缓存,用于将内存的虚拟地址翻译成物理地址,由于TLB的大小有限,
不能缓存的地址就需要访问内存里的page table来进行翻译,速度慢很多。为了尽可能地将地址放进TLB缓存,新的CPU硬件支持比4k更大的页面从而达到减少地址数量的目的,
比如2MB,4MB,甚至1GB的内存页,视不同的硬件而定。”DirectMap4k”表示映射为4kB的内存数量, “DirectMap2M”表示映射为2MB的内存数量,以此类推。
所以DirectMap其实是一个反映TLB效率的指标
DirectMap 1G: 14680064 kB   //表示映射为1G的内存数量(cpu二级内存--》物理地址映射)

参考:
https://man7.org/linux/man-pages/man5/slabinfo.5.html 
https://man7.org/linux/man-pages/man5/proc.5.html   

cpu二级缓存查找,下面输出结果,由于是多核,出现多个

 



释放内存方法有三种(系统默认值是0,释放之后你需要再改回0值)


https://www.kernel.org/doc/Documentation/sysctl/vm.txt   

 1、echo 1 > /proc/sys/vm/drop_caches   作用: 释放 pagecache
 2、echo 2 > /proc/sys/vm/drop_caches   作用: 释放 dentries and inodes
 3、echo 3 > /proc/sys/vm/drop_caches   作用: 释放 pagecache, dentries and inodes

 常用方法是:echo 1 > /proc/sys/vm/drop_caches

 查看与操作 
[root@fp-web-112 ~]# cat /proc/sys/vm/drop_caches 

 0

 [root@fp-web-112 ~]# sync
 [root@fp-web-112 ~]#echo 3 > /proc/sys/vm/drop_caches
 [root@fp-web-112 ~]# cat /proc/sys/vm/drop_caches
 [root@fp-web-112 ~]# free -m
 首先,/proc/sys/vm/drop_caches的值,默认为0
 手动执行sync命令(描述:sync 命令运行 sync 子例程。如果必须停止系统,则运行sync 命令以确保文件系统的完整性。
  sync 命令将所有未写的系统缓冲区写到磁盘中,包含已修改的 i-node、已延迟的块 I/O 和读写映射文件.


linux 内核官网: https://www.kernel.org 
https://www.kernel.org/doc/Documentation 
https://www.kernel.org/doc/Documentation/sysctl/vm.txt
vm.txt有关/proc/sys/vm/drop_caches说明 
 

 

 linux内核参数vm.swappiness

设置linux内核参数vm.swappiness的值,以尽大限度的使用物理内存

Swappiness是Linux内核的一个属性,它定义系统多久使用交换空间一次。
swappiness的值的大小对如何使用swap分区是有着很大的联系的。
swappiness=0的时候表示最大限度使用物理内存,然后才是 swap空间,
swappiness=100的时候表示积极的使用swap分区,并且把内存上的数据及时的搬运到swap空间里面。linux的基本默认设置为60

官网解释如下:
https://www.kernel.org/doc/Documentation/sysctl/vm.txt


sysctl命令作用在运行时配置内核参数,sysctl命令是从/proc/sys目录中读取信息,
/proc/sys是一个虚拟目录,其中包含可用于查看和设置当前内核参数的文件对象
sysctl vm.swappinesscat /proc/sys/vm/swappiness将给出相同的输出

查看参数值
[root@fp-web-112 ~]#cat /proc/sys/vm/swappiness
临时调整
[root@fp-web-112 ~]# sysctl vm.swappiness=10

[root@fp-web-112 ~]# sysctl -q vm.swappiness   

永久设置vm.swappiness

[root@fp-web-112 ~]# echo "vm.swappiness = 10" >> /etc/sysctl.conf
从配置文件“/etc/sysctl.conf”加载内核参数设置,立即生效
[root@fp-web-112 ~]# sysctl -p

 
手动清理释放swap分区占用的内存

 swapon -s 查看开启的swap分区


 

如果出现无法释放掉swap占用的内存的情况下 可以通过前置关闭该设备解决

[root@localhost felix]# swapoff /dev/dm-1


参考文档

https://www.kernel.org/doc/Documentation 
https://www.kernel.org/doc/Documentation/sysctl/vm.txt
https://www.kernel.org/doc/Documentation/filesystems/proc.txt

https://man7.org/linux/man-pages/man5/slabinfo.5.html 
https://man7.org/linux/man-pages/man5/proc.5.html   

 

posted @ 2022-01-26 11:31  jinzi  阅读(1633)  评论(0编辑  收藏  举报