都说 Linux 是吃内存大户,可你知道具体是哪些进程吃掉了吗?
一个经常被问到的 Linux
问题:为啥 Linux
系统没运行多少程序,显示的可用内存这么少?
其实 Linux
与 Windows
的内存管理不同,会尽量缓存内存以提高读写性能,通常叫做Cache Memory
。
比较老的资料都会介绍 Linux
的 Cache
占用很多并没有关系,因为 Linux
会尽可能利用内存进行缓存。但是缓存的回收也是需要资源的,比较好的一篇文章是 Poor Zorro 写的 Linux
内存中的 Cache 真的能被回收么?。
虽然大部分情况下我们看到 Cache
占用很高时是没有问题的,但是我们还是想弄清楚到底是哪个程序把 Cache
弄的那么高,这居然不是一件容易的事。
内核的模块在分配资源的时候,为了提高效率和资源的利用率,都是透过 Slab
来分配的。Slab
为结构性缓存占用内存,该项也经常占用很大的内存。不过借助 slabtop
工具,我们可以很方便的显示内核片缓存信息,该工具可以更直观的显示 /proc/slabinfo
下的内容。
# 显示了一台机器缓存中占用对象的情况
$ slabtop -s c
Active / Total Objects (% used) : 856448 / 873737 (98.0%)
Active / Total Slabs (% used) : 19737 / 19737 (100.0%)
Active / Total Caches (% used) : 67 / 89 (75.3%)
Active / Total Size (% used) : 141806.80K / 145931.33K (97.2%)
Minimum / Average / Maximum Object : 0.01K / 0.17K / 8.00K
OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
416949 416949 100% 0.10K 10691 39 42764K buffer_head
5616 5545 98% 2.00K 351 16 11232K kmalloc-2048
9114 8990 98% 1.02K 294 31 9408K ext4_inode_cache
12404 12404 100% 0.57K 443 28 7088K radix_tree_node
10800 10731 99% 0.58K 400 27 6400K inode_cache
31290 29649 94% 0.19K 745 42 5960K dentry
3552 3362 94% 1.00K 111 32 3552K kmalloc-1024
1100 1055 95% 2.84K 100 11 3200K task_struct
1649 1481 89% 1.88K 97 17 3104K TCP
27000 27000 100% 0.11K 750 36 3000K sysfs_dir_cache
1380 1269 91% 2.06K 92 15 2944K sighand_cache
虽然上面的命令显示了 Cache
中 Slab
的情况,但是还是没有显示什么程序占用的 Cache
。
方案一:使用 Pcstat 来实现
经过搜索,发现 linux-ftools
这个工具可以显示某个文件占用的 Cache
的情况, fincore
只是它其中的一个工具。
$ fincore [options] files...
--pages=false Do not print pages
--summarize When comparing multiple files, print a summary report
--only-cached Only print stats for files that are actually in cache.
https://colobu.com/2017/03/07/what-is-in-linux-cached/root@xxxxxx:/var/lib/mysql/blogindex# fincore --pages=false --summarize --only-cached *
stats for CLUSTER_LOG_2010_05_21.MYI: file size=93840384 , total pages=22910 , cached pages=1 , cached size=4096, cached perc=0.004365
stats for CLUSTER_LOG_2010_05_22.MYI: file size=417792 , total pages=102 , cached pages=1 , cached size=4096, cached perc=0.980392
stats for CLUSTER_LOG_2010_05_23.MYI: file size=826368 , total pages=201 , cached pages=1 , cached size=4096, cached perc=0.497512
stats for CLUSTER_LOG_2010_05_24.MYI: file size=192512 , total pages=47 , cached pages=1 , cached size=4096, cached perc=2.127660
stats for CLUSTER_LOG_2010_06_03.MYI: file size=345088 , total pages=84 , cached pages=43 , cached size=176128, cached perc=51.190476
stats for CLUSTER_LOG_2010_06_04.MYD: file size=1478552 , total pages=360 , cached pages=97 , cached size=397312, cached perc=26.944444
stats for CLUSTER_LOG_2010_06_04.MYI: file size=205824 , total pages=50 , cached pages=29 , cached size=118784, cached perc=58.000000
stats for COMMENT_CONTENT_2010_06_03.MYI: file size=100051968 , total pages=24426 , cached pages=10253 , cached size=41996288, cached perc=41.975764
stats for COMMENT_CONTENT_2010_06_04.MYD: file size=716369644 , total pages=174894 , cached pages=79821 , cached size=326946816, cached perc=45.639645
stats for COMMENT_CONTENT_2010_06_04.MYI: file size=56832000 , total pages=13875 , cached pages=5365 , cached size=21975040, cached perc=38.666667
stats for FEED_CONTENT_2010_06_03.MYI: file size=1001518080 , total pages=244511 , cached pages=98975 , cached size=405401600, cached perc=40.478751
stats for FEED_CONTENT_2010_06_04.MYD: file size=9206385684 , total pages=2247652 , cached pages=1018661 , cached size=4172435456, cached perc=45.321117
stats for FEED_CONTENT_2010_06_04.MYI: file size=638005248 , total pages=155763 , cached pages=52912 , cached size=216727552, cached perc=33.969556
stats for FEED_CONTENT_2010_06_04.frm: file size=9840 , total pages=2 , cached pages=3 , cached size=12288, cached perc=150.000000
stats for PERMALINK_CONTENT_2010_06_03.MYI: file size=1035290624 , total pages=252756 , cached pages=108563 , cached size=444674048, cached perc=42.951700
stats for PERMALINK_CONTENT_2010_06_04.MYD: file size=55619712720 , total pages=13579031 , cached pages=6590322 , cached size=26993958912, cached perc=48.533080
stats for PERMALINK_CONTENT_2010_06_04.MYI: file size=659397632 , total pages=160985 , cached pages=54304 , cached size=222429184, cached perc=33.732335
stats for PERMALINK_CONTENT_2010_06_04.frm: file size=10156 , total pages=2 , cached pages=3 , cached size=12288, cached perc=150.000000
---
total cached size: 32847278080
fincore
的工作原理是将指定文件的相应 Inode Data
与 Kernel
的 Page Cache Table
做对比,如果 Page Cache Table
有这个 Inode
信息,就找到该 Inode
对应的 Data Block
的大小。
因为 Kernel
的 Page Cache Table
只存储 Data Block
的引用而不是文件名,即文件的 Inode
信息。所以并没有任何一个工具运行一次就可以找出所有的文件使用缓存的情况。所以使用 linux-fincore
这个工具也只能加文件名来判断该文件是否被缓存,如果缓存,大小是多少。问题是你不能随便猜哪个文件是否被缓存吧。
Shanker
提供了一个脚本来解决此问题,那就是查看哪些进程使用的物理内存最多,就找到该进程打开的文件,然后用 fincore
来查看这些文件的缓存使用率。
这个办法在大部分情况下都可以找到占用 Cache
较多的程序和进程。脚本内容如下:
#!/bin/bash
#Author: Shanker
#Time: 2016/06/08
#set -e
#set -u
#you have to install linux-fincore
if [ ! -f /usr/local/bin/linux-fincore ]
then
echo "You haven't installed linux-fincore yet"
exit
fi
#find the top 10 processs' cache file
ps -e -o pid,rss|sort -nk2 -r|head -10 |awk '{print $1}'>/tmp/cache.pids
#find all the processs' cache file
#ps -e -o pid>/tmp/cache.pids
if [ -f /tmp/cache.files ]
then
echo "the cache.files is exist, removing now "
rm -f /tmp/cache.files
fi
while read line
do
lsof -p $line 2>/dev/null|awk '{print $9}' >>/tmp/cache.files
done</tmp/cache.pids
if [ -f /tmp/cache.fincore ]
then
echo "the cache.fincore is exist, removing now"
rm -f /tmp/cache.fincore
fi
for i in `cat /tmp/cache.files`
do
if [ -f $i ]
then
echo $i >>/tmp/cache.fincore
fi
done
linux-fincore -s `cat /tmp/cache.fincore`
rm -f /tmp/cache.{pids,files,fincore}
比较遗憾的是,linux-ftools
目前已经不再维护了。在新版本的操作系统上没法编译好这个程序,所以这个方法失效了。
再次通过万能的 Google
搜索,后来我找到了 pcstat
这个工具,pcstat
使用 Go 语言开发,功能基本和 linux-ftools
一样 。
项目地址:https://github.com/tobert/pcstat
然后我修改了 Shanker
的脚本,让它使用 pcstat
来进行处理,这样就可以很好的找到 Cache
所占用的情况。修改后的脚本如下:
#!/bin/bash
#you have to install pcstat
if [ ! -f /data0/brokerproxy/pcstat ]
then
echo "You haven't installed pcstat yet"
echo "run \"go get github.com/tobert/pcstat\" to install"
exit
fi
#find the top 10 processs' cache file
ps -e -o pid,rss|sort -nk2 -r|head -10 |awk '{print $1}'>/tmp/cache.pids
#find all the processs' cache file
#ps -e -o pid>/tmp/cache.pids
if [ -f /tmp/cache.files ]
then
echo "the cache.files is exist, removing now "
rm -f /tmp/cache.files
fi
while read line
do
lsof -p $line 2>/dev/null|awk '{print $9}' >>/tmp/cache.files
done</tmp/cache.pids
if [ -f /tmp/cache.pcstat ]
then
echo "the cache.pcstat is exist, removing now"
rm -f /tmp/cache.pcstat
fi
for i in `cat /tmp/cache.files`
do
if [ -f $i ]
then
echo $i >>/tmp/cache.pcstat
fi
done
/data0/brokerproxy/pcstat `cat /tmp/cache.pcstat`
rm -f /tmp/cache.{pids,files,pcstat}
脚本运行成功后的显示结果如下:
+------------------------------------------+----------------+------------+-----------+---------+
| Name | Size (bytes) | Pages | Cached | Percent |
|------------------------------------------+----------------+------------+-----------+---------|
| /data0/abcasyouknow/0307/abc | 10060771 | 2457 | 2457 | 100.000 |
| /data0/abcasyouknow/0307/logs/abc.log | 1860 | 1 | 1 | 100.000 |
| /data0/abcasyouknow/0307/logs/uuid.log | 326326364 | 79670 | 79670 | 100.000 |
| /usr/bin/bash | 960384 | 235 | 194 | 082.553 |
| /usr/lib/locale/locale-archive | 106065056 | 25895 | 211 | 000.815 |
| /usr/lib64/libnss_files-2.17.so | 58288 | 15 | 15 | 100.000 |
| /usr/lib64/libc-2.17.so | 2107760 | 515 | 336 | 065.243 |
| /usr/lib64/libdl-2.17.so | 19512 | 5 | 5 | 100.000 |
| /usr/lib64/libtinfo.so.5.9 | 174520 | 43 | 42 | 097.674 |
| /usr/lib64/ld-2.17.so | 164336 | 41 | 41 | 100.000 |
| /usr/lib64/gconv/gconv-modules.cache | 26254 | 7 | 7 | 100.000 |
+------------------------------------------+----------------+------------+-----------+---------+
从结果我们可以看到 uuid.log
占用 Cache
比较多。这个文件是打开的,程序一直在往里面写日志,Linux 应该是把它缓存了。
方案二:使用 Vmtouch 来实现
除了上面提到的 pcstat
工具外,你还可以使用 vmtouch
来实现同样的目的。vmtouch
是一个可以查询到缓存的文件和目录,并且能把文件推入缓存或者驱逐出缓存的工具。
项目地址:https://github.com/hoytech/vmtouch
安装 Vmtouch
$ git clone https://github.com/hoytech/vmtouch
$ cd vmtouch
$ make
$ sudo make install
使用 Vmtouch
vmtouch 命令语法
$ vmtouch
vmtouch: no files or directories specified
vmtouch v1.0.2 - the Virtual Memory Toucher by Doug Hoyte
Portable file system cache diagnostics and control
Usage: vmtouch [OPTIONS] ... FILES OR DIRECTORIES ...
Options:
-t touch pages into memory
-e evict pages from memory
-l lock pages in physical memory with mlock(2)
-L lock pages in physical memory with mlockall(2)
-d daemon mode
-m max file size to touch
-p use the specified portion instead of the entire file
-f follow symbolic links
-h also count hardlinked copies
-w wait until all pages are locked (only useful together with -d)
-v verbose
-q quiet
一些使用的例子
由于 vmtouch
直接支持目录级查询,所以使用起来简单得多了。
查看 /tmp 目录在内存中的缓存
$ vmtouch /tmp/
vmtouch: WARNING: skipping non-regular file: /tmp/ssh-GgJnCEkWMQC2/agent.1068
Files: 17
Directories: 7
Resident Pages: 4780/4780 18M/18M 100%
Elapsed: 0.001006 seconds
如果需要查看更详细信息,可以使用 -v
参数。
$ vmtouch -v /tmp/
查看一个文件被缓存了多少
$ vmtouch -v ~/Downloads/phoronix-test-suite_6.0.1_all.deb
/home/neo/Downloads/phoronix-test-suite_6.0.1_all.deb
[ ] 0/132
Files: 1
Directories: 0
Resident Pages: 0/132 0/528K 0%
Elapsed: 0.000117 seconds
把指定的文件缓存起来
$ vmtouch -vt ~/Downloads/phoronix-test-suite_6.0.1_all.deb
/home/neo/Downloads/phoronix-test-suite_6.0.1_all.deb
[OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO] 132/132
Files: 1
Directories: 0
Touched Pages: 132 (528K)
Elapsed: 0.007935 seconds
把缓存中指定的数据驱逐出去
$ vmtouch -ve ~/Downloads/phoronix-test-suite_6.0.1_all.deb
Evicting /home/neo/Downloads/phoronix-test-suite_6.0.1_all.deb
Files: 1
Directories: 0
Evicted Pages: 132 (528K)
Elapsed: 0.000109 seconds
更多关于 vmtouch
使用的具体信息,你可以参考官网:https://hoytech.com/vmtouch/
如果你还有更多 Linux
下查看 Cache
或 Buffer
占用的方法,请直接留言告诉我们哟!
参考文档
https://www.google.com
https://colobu.com/2017/03/07/what-is-in-linux-cached/
https://www.cnblogs.com/langdashu/p/5953222.html
都说 Linux 是吃内存大户,可你知道具体是哪些进程吃掉了吗?相关推荐
- 不可小觑的吃内存大户
工作电脑的内存空间为4G,运行Visual studio或打开多个word文档时各种卡顿,忍无可忍之下,打开"任务管理器"查看,内存使用率达90%,在"任务管理器&quo ...
- linux+cp+吃内存怎么办,Linux吃掉了我的内存
原标题:Linux吃掉了我的内存 来源:海林(@海风林影 ) 链接:http://www.cnblogs.com/hazir/p/linux_ate_my_ram.html 在Windows下资源管理 ...
- linux系统进程的内存布局
内存管理模块是操作系统的心脏:它对应用程序和系统管理非常重要.今后的几篇文章中,我将着眼于实际的内存问题,但也不避讳其中的技术内幕.由于不少概念是通用的,所以文中大部分例子取自32位x86平台的Lin ...
- 上传文件实时显示网速怎么实现_担心PC程序吃内存占网速?有了它终于放心了...
自乔帮主发布iPhone至今,智能手机已经走过了13个年头,其系统.UI.操作逻辑都已经逐步完善且相当傻瓜化. 所以总有许多人切换到PC上时,总感觉缺了那么点东西,Windows系统的生产力自然是毋庸 ...
- 【Linux】Linux进程间通信——共享内存/消息队列/守护进程
文章目录 进程间通信--共享内存/守护进程 一, 共享内存 1. 共享内存概念 2. 共享内存使用 1. 共享内存使用步骤 2. 共享内存操作函数 3. 共享内存常用操作命令 4. 共享内存使用示例: ...
- Linux下找出吃内存的方法总结
linux下查询进程占用的内存方法总结,假设现在有一个「php-cgi」的进程 ,进程id为「25282」.现在想要查询该进程占用的内存大小.linux命令行下有很多的工具进行查看,现总结常见的几种方 ...
- linux sleeping进程多_Linux下找出吃内存的方法总结
linux下查询进程占用的内存方法总结,假设现在有一个「php-cgi」的进程 ,进程id为「25282」.现在想要查询该进程占用的内存大小.linux命令行下有很多的工具进行查看,现总结常见的几种方 ...
- linux双系统内存分配,Linux和Windows硬盘分区设置(二)
三.关于硬盘分区划分标准及合理分区结构 1.硬盘分区划分标准 硬盘的分区由主分区.扩展分区和逻辑分区组成:所以我们在对硬盘分区时要遵循这个标准:主分区(包括扩展分区)的最大个数是四个,主分区(包含扩展 ...
- linux 和windows 内存管理区别
linux 和windows 内存管理区别 在 80 年代初,IBM 推出的 IBM PC 机采用了 Intel 16 位的 8088 处理器,该处 理器可以访问最多 1MB 的存储器.当应用程序需要 ...
- linux系统资源分析 - 内存篇
目录 一.早期的内存使用与内存管理技术演变 二.free命令详解 2.1 基本名词解析 2.2 buffer 与 cache 的区别? 2.3 内存计算公式 2.4 物理内存使用公式 2.4.1 只有 ...
最新文章
- Powerdesigner逆向工程64位Oracle数据库
- CSS粘住固定底部的5种方法
- Intel Realsense D435 关于开放环境下的目标识别 曝光量参数的自动设定机制
- python中repeat函数用法
- python基础——递归函数
- ANTLR和网络:一个简单的例子
- JQuery通过后台获取数据遍历到前台
- 2,上传电影,udp,异常处理,socketserver
- C++实现对数学基本运算表达式的解析
- 第 1 章 多线程基础介绍
- 如何阻止机器人杀害人类?
- css让文本不会被选中,鼠标变小手
- Linux系统移植(第2版)
- QBadgeView小红点的简单使用
- ActiveMQ 之安全认证
- html背景图怎么调亮度,不得不知的ps技巧-亮度与背景图设置
- 程序员写在猝死的前一天
- 济南86公里综合管廊,CBD近万地下车位已建成
- 最全总结---36种MySQL时间函数
- matlab flatten,Numpy中扁平化函数ravel()和flatten()的区别
热门文章
- nyoj 破门锁(水题)
- SWT/JFace常用组件----容器类
- poj 2406 Power Strings kmp基础
- Wolfram Mathematica 13 for Mac(功能广泛的科学计算软件)中文版
- Illustrator教程,如何在 Illustrator 中创建和应用图案?
- Ps 初学者教程,如何使用修复画笔工具修整照片?
- 如何解决 MacBook Pro Touch ID不起作用?
- Springboot中如何在Utils类中使用@Autowired注入bean
- yum仓库中源的配置与使用
- 学习笔记之正则表达式