Linux内存查看及一次释放Linux内存问题处理(Aliyun ecs)

来自linux中国网wiki
Evan讨论 | 贡献2021年10月20日 (三) 02:48的版本 →‎2. 问题来了
(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)
跳到导航 跳到搜索

free命令buff/cache过高的一般处理办法

sync 
echo 1 > /proc/sys/vm/drop_caches #:表示清除pagecache。#This command will clear pagecache:
echo 2 > /proc/sys/vm/drop_caches #:表示清除回收slab分配器中的对象(包括目录项缓存和inode缓存)。slab分配器是内核中管理内存的一种机制,其中很多缓存数据实现都是用的pagecache。 #To clear dentries and inodes you can use:
echo 3 > /proc/sys/vm/drop_caches #:表示清除pagecache和slab分配器中的缓存对象。To free memory of the all above use a following command:
 
能会遇到了 "bash: /proc/sys/vm/drop_caches: Permission denied"的问题,即使加上sudo也不行.

原因:重定向符号 “>” 和 ">>" 也是 bash 的命令。使用 sudo 只是让 echo 命令具有了 root 权限,但是没有让 “>” 和 ">>" 命令也具有 root 权限,所以 bash 会认为这两个命令都没有向 drop_caches 文件写入信息的权限。

解决方法:

方法一是利用 "sh -c" 命令,它可以让 bash 将一个字串作为完整的命令来执行,这样就可以将 sudo 的影响范围扩展到整条命令。具体用法如下:

$ sudo sh -c 'echo 3 > /proc/sys/vm/drop_caches'

方法二是利用管道和 tee 命令,该命令可以从标准输入中读入信息并将其写入标准输出或文件中,具体用法如下:

$ echo 3 | sudo tee -a /proc/sys/vm/drop_caches

注意,tee 命令的 "-a" 选项的作用等同于 ">>" 命令,如果去除该选项,那么 tee 命令的作用就等同于 ">" 命令。


1.linux查看的一般方法:

按照离CPU由近到远的顺序依次是CPU寄存器、Cache、内存、硬盘,越靠近CPU的存储器容量越小但访问速度越快

1).free -m  # or free -g 
常用参数为 -m  -g  -h   -s 
#注意 正常情况下free不能太小  不能有swap used 不然一般是有问题的,虽然说少量地使用swap是不是影响到系统性能的 
[root@vm ~]# free -m 
             total       used       free     shared    buffers     cached
Mem:           999        256        743          0         21        136
-/+ buffers/cache:         99        900
Swap:         2015          0       2015

2). top ->M 
一般就可以看到这些使用内存比较多的程序的 
如果这两个看到的不多,但是free很少 那就是有问题了 如昨天

2. 问题来了

Q: Linux系统used内存占用很大,而实际系统中个进程并没有占用这么多内存
[root@evan]# free -m 
             total       used       free     shared    buffers     cached
Mem:         15950      15229        721          0        331       1020

[root@ ~]# top 
Mem:  16333644k total, 15589488k used,   744156k free,   339752k buffers
Swap:        0k total,        0k used,        0k free,  1044796k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                           
 1993 redis     20   0  150m  25m 1144 S  0.7  0.2 373:35.07 mem-server                                      
               20   0 39720  23m 1660 S  0.0  0.1   0:04.27 apache                                             
 
重启了常用的服务还是不行  

原因 :
这是因为linux的缓存机制造成的 可以使用下面的方法测试下

#释放前sync一下,防止丢数据。

至于 sync 命令。它和 cached 有关。它的功能是,把脏页写回磁盘,也就是把修改过的数据还没写到磁盘的数据写到磁盘上。因为内核会延迟提交,每次提交多积累一些数据,以提高效率、降低延迟。没有使用的必要,只会让系统卡一下而已
https://segmentfault.com/q/1010000002439931

sync #释放内存前先使用sync命令做同步,以确保文件系统的完整性,将所有未写的系统缓冲区写到磁盘中,包含已修改的 i-node、已延迟的块 I/O 和读写映射文件。否则在释放缓存的过程中,可能会丢失未保存的文件。
#释放
echo 3 > /proc/sys/vm/drop_caches 

drop_caches的值可以是0-3之间的数字,代表不同的含义:
0:不释放(系统默认值)
1:释放页缓存
2:释放dentries和inodes
3:释放所有缓存

# 这个是有可能影响业务的,建议在适当的时间清理一下
#释放完内存后改回去让系统重新自动分配内存。
echo 0 > /proc/sys/vm/drop_caches 
# /usr/bin/echo: 写入错误: 无效的参数  centos7  Oct20 2021

处理后 
[root@evan]# free -m 
             total       used       free     shared    buffers     cached
Mem:         15950        433      15517          0          3         31


处理问题用到的知识点如下 
######### Linux释放内存的相关知识 ###############

在Linux系统下,我们一般不需要去释放内存,因为系统已经将内存管理的很好。但是凡事也有例外,有的时候内存会被缓存占用掉,导致系统使用SWAP空 间影响性能,例如当你在linux下频繁存取文件后,物理内存会很快被用光,当程序结束后,内存不会被正常释放,而是一直作为caching。,此时就需 要执行释放内存(清理缓存)的操作了。

Linux系统的缓存机制是相当先进的,他会针对dentry(用于VFS,加速文件路径名到inode的转换)、Buffer Cache(针对磁盘块的读写)和Page Cache(针对文件inode的读写)进行缓存操作。但是在进行了大量文件操作之后,缓存会把内存资源基本用光。但实际上我们文件操作已经完成,这部分 缓存已经用不到了。这个时候,我们难道只能眼睁睁的看着缓存把内存空间占据掉吗?所以,我们还是有必要来手动进行Linux下释放内存的操作,其实也就是 释放缓存的操作了。/proc是一个虚拟文件系统,我们可以通过对它的读写操作做为与kernel实体间进行通信的一种手段.也就是说可以通过修改 /proc中的文件,来对当前kernel的行为做出调整.那么我们可以通过调整/proc/sys/vm/drop_caches来释放内存。要达到释 放缓存的目的,我们首先需要了解下关键的配置文件/proc/sys/vm/drop_caches。这个文件中记录了缓存释放的参数,默认值为0,也就 是不释放缓存。

一般复制了文件后,可用内存会变少,都被cached占用了,这是linux为了提高文件读取效率的做法:为了提高磁盘存取效率, Linux做了一些精心的设计, 除了对dentry进行缓存(用于VFS,加速文件路径名到inode的转换), 还采取了两种主要Cache方式:Buffer Cache和Page Cache。前者针对磁盘块的读写,后者针对文件inode的读写。这些Cache有效缩短了 I/O系统调用(比如read,write,getdents)的时间。"

########################

2020
改默认为0 的时候报这个错是正常的,无法修改为0,您可以参考一下:
https://www.dazhuanlan.com/2019/10/05/5d986e3c55468/

这边处理重启后会自动重置为0,如果不重启,是会自动恢复为0,您可以参考如下文档:
http://bbs.chinaunix.net/thread-4231822-1-1.html  

3.知识点:

free命令可以显示Linux系统中空闲的、已用的物理内存及swap内存,及被内核使用的buffer。在Linux系统监控的工具中,free命令是最经常使用的命令之一。 常用参数为 -m  -g  -h   -s 

命令功能:
free 命令显示系统使用和空闲的内存情况,包括物理内存、交互区内存(swap)和内核缓冲区内存。共享内存将被忽略
命令参数:

-b  以Byte为单位显示内存使用情况。 
-k  以KB为单位显示内存使用情况。 
-m  以MB为单位显示内存使用情况。
-g   以GB为单位显示内存使用情况。 
-o  不显示缓冲区调节列。 
-s<间隔秒数>  持续观察内存使用状况。 
-t  显示内存总和列。 
-V  显示版本信息。 

root@service]# free
             total       used       free     shared    buffers     cached
Mem:      32940112   30841684    2098428          0    4545340   11363424
-/+ buffers/cache:   14932920   18007192
Swap:     32764556    1944984   30819572

下面是对这些数值的解释:
total:总计物理内存的大小。
used:已使用多大。
free:可用有多少。
Shared:多个进程共享的内存总额。
Buffers/cached:磁盘缓存的大小。
第三行(-/+ buffers/cached):
used:已使用多大。
free:可用有多少。
第四行是交换分区SWAP的,也就是我们通常所说的虚拟内存。
区别:第二行(mem)的used/free与第三行(-/+ buffers/cache) used/free的区别。 这两个的区别在于使用的角度来看,第一行是从OS的角度来看,因为对于OS,buffers/cached 都是属于被使用,所以他的可用内存是2098428KB,已用内存是30841684KB,其中包括,内核(OS)使用+Application(X, oracle,etc)使用的+buffers+cached.
第三行所指的是从应用程序角度来看,对于应用程序来说,buffers/cached 是等于可用的,因为buffer/cached是为了提高文件读取的性能,当应用程序需在用到内存的时候,buffer/cached会很快地被回收。
所以从应用程序的角度来说,可用内存=系统free memory+buffers+cached。
如本机情况的可用内存为:
18007156=2098428KB+4545340KB+11363424KB

那buffers和cached都是缓存,两者有什么区别呢?
为了提高磁盘存取效率, Linux做了一些精心的设计, 除了对dentry进行缓存(用于VFS,加速文件路径名到inode的转换), 还采取了两种主要Cache方式:Buffer Cache和Page Cache。前者针对磁盘块的读写,后者针对文件inode的读写。这些Cache有效缩短了 I/O系统调用(比如read,write,getdents)的时间。
磁盘的操作有逻辑级(文件系统)和物理级(磁盘块),这两种Cache就是分别缓存逻辑和物理级数据的。
Page cache实际上是针对文件系统的,是文件的缓存,在文件层面上的数据会缓存到page cache。文件的逻辑层需要映射到实际的物理磁盘,这种映射关系由文件系统来完成。当page cache的数据需要刷新时,page cache中的数据交给buffer cache,因为Buffer Cache就是缓存磁盘块的。但是这种处理在2.6版本的内核之后就变的很简单了,没有真正意义上的cache操作。
Buffer cache是针对磁盘块的缓存,也就是在没有文件系统的情况下,直接对磁盘进行操作的数据会缓存到buffer cache中,例如,文件系统的元数据都会缓存到buffer cache中。
简单说来,page cache用来缓存文件数据,buffer cache用来缓存磁盘数据。在有文件系统的情况下,对文件操作,那么数据会缓存到page cache,如果直接采用dd等工具对磁盘进行读写,那么数据会缓存到buffer cache。
所以我们看linux,只要不用swap的交换空间,就不用担心自己的内存太少.如果常常swap用很多,可能你就要考虑加物理内存了.这也是linux看内存是否够用的标准.
如果是应用服务器的话,一般只看第二行,+buffers/cache,即对应用程序来说free的内存太少了,也是该考虑优化程序或加内存了。


每天一个linux命令(45):free 命令
http://www.cnblogs.com/peida/archive/2012/12/25/2831814.html

http://www.cnblogs.com/coldplayerest/archive/2010/02/20/1669949.html

手动释放Linux内存的方法
http://www.cnblogs.com/waterdragon/archive/2013/03/01/2938289.html

Linux服务器Cache占用过多内存导致系统内存不足问题的排查解决
http://www.cnblogs.com/panfeng412/p/drop-caches-under-linux-system.html

Linux Used内存到底哪里去了?
http://blog.yufeng.info/archives/2456

http://www.myjishu.com/?p=82

http://www.cnblogs.com/xd502djj/archive/2011/03/01/1968041.html

4.其它常用命令

获得当前系统中运行的最占内存的前10个程序:
ps aux | sort -k 6 -rn | head -n10
ps aux| grep -v "USER" |sort -n -r -k 4 |awk 'NR==1{ print $0}'
ps aux --sort -rss

pmap PID #查看静态内存使用情况
top #按shift+m 按照内存使用情况进行排序。 
ps -ef | grep apache #查看PID 比如是1234
cat /proc/1234/status #查看详细的信息

top -b -n  1 | grep apache
top -b -n 1 |grep apache |awk '{print "cpu:"$9"%","mem:"$10"%"}'

cat /proc/meminfo
ps -eo pid,args,rss|grep apache|grep -v grep|awk ‘{a+=$NF}END{print a}’
 

然后top看了下,没有特别吃内存的程序。用ps大概统计下所有程序占用的总内存
差不多8g

[root@prod-1 ~]# ps aux | awk '{mem += $6} END {print mem/1024/1024}'
7.9253

  http://www.cnblogs.com/panfeng412/p/drop-caches-under-linux-system.html
 sar 找出系统瓶颈的利器
 
yum install -y  sysstat && echo 'ENABLED=”true”' > /etc/default/sysstat && /etc/init.d/sysstat start
 sar -q: 查看平均负载
 
 sar参数说明

-A 汇总所有的报告
-a 报告文件读写使用情况
-B 报告附加的缓存的使用情况
-b 报告缓存的使用情况
-c 报告系统调用的使用情况
-d 报告磁盘的使用情况 
-g 报告串口的使用情况
-h 报告关于buffer使用的统计数据
-m 报告IPC消息队列和信号量的使用情况
-n 报告命名cache的使用情况
-p 报告调页活动的使用情况
-q 报告运行队列和交换队列的平均长度
-R 报告进程的活动情况
-r 报告没有使用的内存页面和硬盘块
-u 报告CPU的利用率
-v 报告进程、i节点、文件和锁表状态
-w 报告系统交换活动状况
-y 报告TTY设备活动状况
 
 http://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/sar.html

执行过程

[root@prod-sns ~]# sync 
[root@prod-sns- ~]# free -m 
              total        used        free      shared  buff/cache   available
Mem:           7821        3868         332        2288        3619        1323
Swap:             0           0           0
[root@prod-sns1 ~]# echo 1 > /proc/sys/vm/drop_caches
[root@prod-sns ~]# free -m 
              total        used        free      shared  buff/cache   available
Mem:           7821        3868        1349        2288        2602        1336
Swap:             0           0           0
[root@prod-sns- ~]# sync 
[root@prod-sns ~]# echo 2 > /proc/sys/vm/drop_caches
[root@prod-sns1 ~]# free -m 
              total        used        free      shared  buff/cache   available
Mem:           7821        3868        1344        2288        2607        1339
Swap:             0           0           0

[root@prod-sns ~]# sync 
[root@prod-sns ~]# echo 3 > /proc/sys/vm/drop_caches
[root@prod-sns-1 ~]# free -m 
              total        used        free      shared  buff/cache   available
Mem:           7821        3867        1376        2288        2576        1350
Swap:             0           0           0

还有问题 2020

以前执行的 现在执行了也没有效果 应该只能重启vm

内核珠玑:/proc/sys/vm/drop_caches为啥不灵了

2020的一些办法 没试过

解决办法:
1.运行 sync 将 dirty 的内容写回硬盘
$sync

2.通过修改 proc 系统的 drop_caches 清理free的cache
$echo 3 > /proc/sys/vm/drop_caches

  3 . 修改/etc/sysctl.conf 添加如下选项后就不会内存持续增加
vm.dirty_ratio = 1
vm.dirty_background_ratio=1
vm.dirty_writeback_centisecs=2
vm.dirty_expire_centisecs=3
vm.drop_caches=3
vm.swappiness =100
vm.vfs_cache_pressure=163
vm.overcommit_memory=2
vm.lowmem_reserve_ratio=32 32 8
kern.maxvnodes=3


drop_caches 的详细文档如下:

Writing to this will cause the kernel to drop clean caches, dentries and inodes from memory, causing that memory to become free.
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
As this is a non-destructive operation, and dirty objects are notfreeable, the user should run "sync" first in order to make sure allcached objects are freed.
This tunable was added in 2.6.16.

上面的设置比较粗暴,使cache的作用基本无法发挥。需要根据机器的状况进行适当的调节寻找最佳的折衷

see also

good echo N>/proc/sys/vm/drop_caches清理缓存

Linux中buff-cache占用过高解决手段

记一次内存占用问题的调查过程


手工释放linux内存——/proc/sys/vm/drop_caches