文章目录

  • 1. 问题说明
  • 2. 折腾之路
    • 2.1 Slab简介
      • 2.1.1 Slab有两个主要作用:
      • 2.1.2 Slab的信息记录
    • 2.2 dentry 简介
      • 2.2.1 dentry清空方案
    • 2.3 SystemTap简介
      • 2.3.1 SystemTap 安装
    • 2.4. 使用systemTap来监控对dentry的使用
      • 2.4.1 从用户进程调用上来统计
      • 2.4.2 curl请求bug的发现
  • 3 . 数据样例附
  • 参考

1. 问题说明

  在国庆的最后一天夜里,服务器突然报警,爆的是内存不够使用了,剩余不到5%。因为该服务器上暂时只运行了一个logstash节点,服务器内存是31g,logstash的jvm堆的大小设置的是24g。看到报警第一反应是,我靠,又发生堆外内存泄漏了?上了服务器,使用top一看,对应的logstash确实只使用24g,对应的其他进程的消耗都很小,加起来不过25g的样子,但是使用free -h一看,却是已经使用了比较高的内存。显示只有1g的缓存了,对应top的话有5g左右的差距,系统按说不应该占用这么多啊。没办法,先解决报警吧。就临时将logstash的jvm内存调整到22g,然后重启。后面再慢慢的排查这个问题。

下面的排查数据都是重启后的,但是依然可以说明问题
1.使用top,free查看相关信息

top -n1
...PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
24407 deploy    20   0 28.0g  19g  17m S 59.4 61.5   6873:35 java
14900 deploy    20   0 1389m 306m 8632 S 29.7  1.0   2905:33 node6352 deploy    20   0  3324 1356  536 R  4.0  0.0   0:00.02 jq-linux641 root      20   0 19348 1192  880 S  0.0  0.0   0:39.53 init2 root      20   0     0    0    0 S  0.0  0.0   0:00.00 kthreadd3 root      RT   0     0    0    0 S  0.0  0.0   6:24.71 migration/0
...

这里从RES可以看到用户进程最多消耗的内存是19g+306m 可以认为不到20g
我们再来看看free命令的情况

free -htotal       used       free     shared    buffers     cached
Mem:           31G        29G       2.3G       204K       392M       4.5G
-/+ buffers/cache:        24G       7.2G
Swap:           0B         0B         0B

可以看到从用户角度看到的进程使用的总内存是24G,这里面有4G左右的偏差,理论上系统不可能占用这么多,而且也会再top中显示的啊。

2.系统内核

cat /etc/issue
CentOS release 6.8 (Final)cat /proc/version
Linux version 2.6.32-642.6.2.el6.x86_64 (mockbuild@worker1.bsys.centos.org) (gcc version 4.4.7 20120313 (Red Hat 4.4.7-17) (GCC) ) #1 SMP Wed Oct 26 06:52:09 UTC 2016

2. 折腾之路

这4g的内存到底去了哪里了呢,不知道的话心里总是很痒,难受。首先,这里的表现是topfree显示不一致,想要搞明白这俩命令的统计原理有点费劲,google一下,没有找到。后来同事帮忙用free可用内存偏少关键字找到了这样一篇文章,这才解开了这个问题的面纱。
原来是free相对top没有专门统计Slab。这也是导致两者差别的主要原因。
这个时候想到可以看看内存的具体的数据对照一下
可以使用 cat /proc/meminfo看到内存的更具体的使用情况

cat /proc/meminfo  |sort -nr -k2
VmallocTotal:   34359738367 kB
VmallocChunk:   34359647340 kB
MemTotal:       32880228 kB
DirectMap1G:    31457280 kB
Committed_AS:   25446604 kB
Active:         22905908 kB
AnonPages:      20760828 kB
Active(anon):   20760796 kB
AnonHugePages:  20178944 kB
CommitLimit:    16440112 kB
Cached:          4765532 kB
# 这里可以看到这一项,确实是4g
Slab:            4262432 kB
SReclaimable:    4225944 kB
Inactive:        3022820 kB
Inactive(file):  3022640 kB
MemFree:         2416988 kB
Active(file):    2145112 kB
DirectMap2M:     2091008 kB
Buffers:          402364 kB
VmallocUsed:       68888 kB
Mapped:            50108 kB
PageTables:        48848 kB
SUnreclaim:        36488 kB
KernelStack:        6176 kB
DirectMap4k:        5992 kB
Hugepagesize:       2048 kB
Shmem:               204 kB
Inactive(anon):      180 kB
Dirty:               152 kB
WritebackTmp:          0 kB
Bounce:                0 kB
...后面还有一些都是0,忽略了

2.1 Slab简介

Slab是内核中使用的数据结构,为了适应更小的数据分配(比页小很多,页通常是4k)。
更加具体的可以参看这里

2.1.1 Slab有两个主要作用:

  • Slab对小对象进行分配,不用为每个小对象分配一个页,节省了空间。
  • 内核中一些小对象创建析构很频繁,Slab对这些小对象做缓存,可以重复利用一些相同的对象,减少内存分配次数。

2.1.2 Slab的信息记录

** 1.Slab的统计信息 **
统计信息记录在/proc/meminfo中对应的项是
Slab,SReclaimable,SUnreclaim
其中Slab=SReclaimable+SUnreclaim,SReclaimable表示可回收使用的内存。

cat /proc/meminfo  |egrep "Slab|SReclaimable|SUnreclaim"
Slab:            4262724 kB
SReclaimable:    4226028 kB
SUnreclaim:        36696 kB

** 2. Slab 详情 **
Slab详细包含的项存储在/proc/slabinfo当中

cat /proc/slabinfo|sort -nr -k2#名称              active对象     总对象     对象大小
# name            <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : slabdata <active_slabs> <num_slabs> <sharedavail>
dentry            20060551      20061020     192            20                 1 : tunables  120       60             8 : slabdata 1003051       1003051      0
buffer_head       1053268       1053390      104            37                 1 : tunables  120       60             8 : slabdata  28470        28470      0
ext3_inode_cache   58426        58445        800             5                 1 : tunables   54       27             8 : slabdata  11689        11689      0
size-64            48788        50209         64            59                 1 : tunables  120       60             8 : slabdata    851          851    480
radix_tree_node    43129        43204        560             7                 1 : tunables   54       27             8 : slabdata   6172         6172      0
size-32            19176        19488         32           112                 1 : tunables  120       60             8 : slabdata    174          174      0
ext4_inode_cache   11222        20140       1000             4                 1 : tunables   54       27             8 : slabdata   5035         5035      0
inotify_inodm..    10037        10080        120            32                 1 : tunables  120       60             8 : slabdata    315          315      0
sysfs_dir_cache     9280         9288        144            27                 1 : tunables  120       60             8 : slabdata    344          344      0
selinux_inod..      7610         7844         72            53                 1 : tunables  120       60             8 : slabdata    148          148      0
vm_area_struct      7212         9044        200            19                 1 : tunables  120       60             8 : slabdata    476          476     24
anon_vma_chain      6202         8701         48            77                 1 : tunables  120       60             8 : slabdata    113          113     24
inode_cache         5952         5952        592             6                 1 : tunables   54       27             8 : slabdata    992          992      0
proc_inode_cache    5839         6072        656             6                 1 : tunables   54       27             8 : slabdata   1012         1012      0
anon_vma            4234         5762         56            67                 1 : tunables  120       60             8 : slabdata     86           86      0
filp                2167         4110        256            15                 1 : tunables  120       60             8 : slabdata    274          274    480
size-192            1985         2120        192            20                 1 : tunables  120       60             8 : slabdata    106          106      0
size-128            1982         2220        128            30                 1 : tunables  120       60             8 : slabdata     74           74      0
size-1024           1913         2136       1024             4                 1 : tunables   54       27             8 : slabdata    534          534    118

这里主要介绍一下前几个列的含义,如上中文注释,这个文件显示了slab使用的详细分布。这里可以看到dentry 占用的是最大的,他占用的内存可以这样计算
20061020*192/1024=3851727kb 可以得到对应的kb size 。

这个文件还有一个更简单的命令可以看:slabtop

这里可以看到各个维度的总结性信息以及详情,而且自动排序了。同样也是dentry占用最多,但是对应的是cache-size和上面计算出来的不一样,不清楚是不是因为slab是从页中分配出来的所以导致页有空闲导致的。

slabtop -o|head -20Active / Total Objects (% used)    : 21372898 / 21401792 (99.9%)Active / Total Slabs (% used)      : 1062385 / 1062554 (100.0%)Active / Total Caches (% used)     : 99 / 177 (55.9%)Active / Total Size (% used)       : 3982075.22K / 3995162.08K (99.7%)Minimum / Average / Maximum Object : 0.02K / 0.19K / 4096.00KOBJS    ACTIVE   USE OBJ-SIZE  SLABS    OBJ/SLAB CACHE-SIZE NAME
20061120 20060914  99%    0.19K 1003056       20   4012224K   dentry
1054685 1054592    99%    0.10K  28505       37    114020K    buffer_head58550  58528      99%    0.78K  11710        5     46840K    ext3_inode_cache51271  48907      95%    0.06K    869       59      3476K    size-6443218  43152      99%    0.55K   6174        7     24696K    radix_tree_node20140  11226      55%    0.98K   5035        4     20140K    ext4_inode_cache19488  19057      97%    0.03K    174      112       696K    size-3210080  10037      99%    0.12K    315       32      1260K    inotify_inode_mark_entry9633   7502      77%    0.20K    507       19      2028K    vm_area_struct9288   9280      99%    0.14K    344       27      1376K    sysfs_dir_cache8701   6437      73%    0.05K    113       77       452K    anon_vma_chain7844   7610      97%    0.07K    148       53       592K    selinux_inode_security6114   5955      97%    0.64K   1019        6      4076K    proc_inode_cache

可以看到,这里的dentry 是最多的,那么dentry又是什么东西呢?

2.2 dentry 简介

dentry (directory entry),目录项缓存。也就是内核中用来作为目录的索引,和inode 共同标识了文件系统,inode 存储的是文件的元信息,dentry存储的是文件名加目录的信息,为了快速定位文件。
所以在文件特别多的情况下有可能会导致dentry量比较大。具体介绍参看这里
在文件比较多或者频繁删除创建文件的时候可能会导致dentry比较多。这个是最直接的原因。如何查看系统的文件,inode数量。

df -iFilesystem      Inodes  IUsed   IFree IUse% Mounted on
/dev/vda1      3276800 714264 2562536   22% /
/dev/vdb       5242880  90647 5152233    2% /home

inodes的数量就代表了dentry的最大数量,可以看到3276800和dentry的数量完全不在一个数量级,所以肯定不是因为系统中的文件太多导致。
但是具体是哪些进程使用了dentry有些难以判断,系统没有直接的信息进行记录。这个时候需要使用大杀器 SystemTap了。

2.2.1 dentry清空方案

系统默认内存回收配置在/proc/sys/vm/drop_caches中

0:不做任何处理,由系统自己管理
1:清空pagecache
2:清空dentries和inodes
3:清空pagecache、dentries和inodes

所以如果想清空dentry,只需要

echo "2" >  /proc/sys/vm/drop_caches等待slab有效下降以后,再恢复
echo "0" >  /proc/sys/vm/drop_caches

2.3 SystemTap简介

SystemTap是一个Linux非常有用的调试(跟踪/探测)工具,常用于Linux
内核或者应用程序的信息采集,比如:获取一个函数里面运行时的变
量、调用堆栈,甚至可以直接修改变量的值,对诊断性能或功能问题非
常有帮助。SystemTap提供非常简单的命令行接口和很简洁的脚本语
言,以及非常丰富的tapset和例子。 类似于java的btrace一样,可以用来调试c的调用等。

这个玩意儿太强大了,只是我用的还不是很熟悉,后面有机会了需要继续学习。简单介绍一下安装吧。

2.3.1 SystemTap 安装

安装步骤不算太难,但是网上说的乱七八糟的,很坑,总结一下我的吧。

1. 安装依赖包
SystemTap有一些依赖包,所以要先装这些依赖包。
依赖包有以下3个

  • kernel-debuginfo
  • kernel-debuginfo-common
  • kernel-devel
    这三个包都是和操作系统的内核版本相关的,所以要先查看内核版本
uname -a
Linux 2.6.32-642.6.2.el6.x86_64 #1 SMP Wed Oct 26 06:52:09 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

所以对应的三个包分别是

kernel-debuginfo-2.6.32-642.6.2.el6.x86_64.rpm
kernel-debuginfo-common-x86_64-2.6.32-642.6.2.el6.x86_64.rpm
kernel-devel-2.6.32-642.6.2.el6.x86_64.rpm

建议直接google,然后找到对应的ftp服务器wget下载,我这边也示例以下吧

wget http://ftp.riken.jp/Linux/scientific/6.2/archive/debuginfo/kernel-debuginfo-2.6.32-642.6.2.el6.x86_64.rpm
wget http://ftp.riken.jp/Linux/scientific/6.2/archive/debuginfo/kernel-debuginfo-2.6.32-642.6.2.el6.x86_64.rpm
wget http://ftp.riken.jp/Linux/scientific/6.2/archive/debuginfo/kernel-debuginfo-common-x86_64-2.6.32-642.6.2.el6.x86_64.rpm

然后安装这三个包

rmp -ivh *.rpm

2. yum 安装SystemTap
接下来就简单了
为了部署 SystemTap,需要安装以下两个 RPM 包:

  • systemtap
  • systemtap-runtime
echo "y" | yum install systemtap systemtap-runtime

2.4. 使用systemTap来监控对dentry的使用

2.4.1 从用户进程调用上来统计

这两个函数对应的是对dentry的申请和释放,所以通过对这两个函数的调用可以看到对应的对dentry的使用情况。

cat name_record.stpprobe kernel.function("d_alloc")
{printf("%s[%ld] %s %s\n", execname(), pid(), pp(), probefunc())
}
probe kernel.function("d_free")
{printf("%s[%ld] %s %s\n", execname(), pid(), pp(), probefunc())
}
probe timer.s(600)
{exit()
}

使用命令 stap name_record.stpn > name.log即可获取相关的信息,name.log中的内容是下面这个样子的。

vim name.logYDService[26276] kernel.function("d_alloc@fs/dcache.c:968") d_alloc
YDService[26276] kernel.function("d_free@fs/dcache.c:89") d_free
...
05.nodes_only_b[10880] kernel.function("d_free@fs/dcache.c:89") d_free
05.nodes_only_b[10531] kernel.function("d_free@fs/dcache.c:89") d_free
05.nodes_only_b[10531] kernel.function("d_alloc@fs/dcache.c:968") d_alloc
...
curl[10650] kernel.function("d_alloc@fs/dcache.c:968") d_alloc
curl[10650] kernel.function("d_free@fs/dcache.c:89") d_free
curl[10650] kernel.function("d_alloc@fs/dcache.c:968") d_alloc
curl[10650] kernel.function("d_free@fs/dcache.c:89") d_free

可以看到是哪个进程调用了这两个函数。这两个函数是进程可以主动进行调用的。

统计一下对应的进程调用

# 总量26w
wc -l name.log
269715 name.log# 按照进程排序
awk '{print $1}' name.log|sort  |uniq -c|sort -n -k1  |tail -n301563 05.nodes_only_b[1698]1563 05.nodes_only_b[19280]1563 05.nodes_only_b[4655]1563 05.nodes_only_b[7605]1564 05.nodes_only_b[16327]1564 05.nodes_only_b[25307]1644 kk-superman-age[23735]2166 sadc[13116]2299 sadc[16307]2299 sadc[22276]2299 sadc[25301]2299 sadc[4659]2300 sadc[1697]2300 sadc[19281]2300 sadc[28249]2300 sadc[31200]2300 sadc[7594]2320 barad_agent[3897]4250 falcon-agent[21818]5574 curl[27094]6503 curl[15143]6759 curl[30036]6796 curl[516]6860 curl[9376]6956 curl[6437]7024 curl[21094]7055 curl[24071]7063 curl[18113]7148 curl[3494]72149 YDService[26276]

可以看到如果按照进程来算的话是YDService 是最多的。先验证一下这个服务。

$ cat name.log |grep "YD"|grep 'd_free'|wc -l
36467
$ cat name.log |grep "YD"|grep 'd_alloc'|wc -l
36572

可以看到这个服务free和alloc的量基本上是一致的,所以没有啥问题。

然后我们再来校验一下curl(因为之前看文档说curl在请求https的时候某写版本是有问题的,所以将所有的curl请求当做一个进程来处理)


$ cat name.log |grep "curl"|grep 'd_alloc'|wc -l
68294
$ cat name.log |grep "curl"|grep 'd_free'|wc -l
738

这一个看,差的好大,估计就是这个了,计算一下按照这个量每分钟产生的大小。
(68294-738)*192/1024/10=1266kb

然后写了一个脚本来记录每分钟的slab,dentry的变换量

#/bin/bashlog_file="$(cd $(dirname $0);pwd)/log_slab.log"
if [ ! -e $log_file ] ;
then echo "time                       slab-kb     dentry-kb      diff    dentry_add" > $log_fileecho "2019.10.09-21:01:19        2929348      2685424       243924" >> $log_file
fidentry_size=$( /usr/bin/slabtop -o|grep dentry |awk '{print $7}'|sed -e "s/K//g")
slab_size=$( cat /proc/meminfo | grep Slab|awk  '{print $2}')
cur_time=$(date +'%Y.%m.%d-%H:%M:%S')
diff_s_d=$(echo "${slab_size}-${dentry_size}"|bc)lastest_dentry=$(tail -n1 ${log_file}|awk '{print $3}')
diff_dentry=$(echo "${dentry_size} - ${lastest_dentry}"|bc)res="${cur_time}        ${slab_size}      ${dentry_size}       ${diff_s_d}      ${diff_dentry}"
echo "$res" >> ${log_file}

然后加到定时任务当中

crontab -e * * * * * bash /home/xx/dentry_record_/record.sh

后面可以看到每分钟的增量大概是

[deploy@bj3-search-log-logstash01 dentry_record_]$ head -30 log_slab.log
time                       slab-kb     dentry-kb      diff       dentry_add
2019.10.09-21:16:01        2950764      2707576       243188      0
2019.10.09-21:17:01        2951940      2708652       243288      1076
2019.10.09-21:18:01        2953528      2710272       243256      1620
2019.10.09-21:19:01        2955564      2711804       243760      1532
2019.10.09-21:20:01        2956880      2713420       243460      1616
2019.10.09-21:21:01        2958904      2715032       243872      1612

可以看到的是和上面计算的1266kb也是比较接近的。

  这个时候发现我的定时任务中有一个监控脚本,里面是对es集群的监控(每分钟运行一次),curl请求获取es信息使用的是http方式,之前做过一些测试http是不会导致dentry上升的。里面用到https的地方就是如果集群由问题会使用钉钉进行报警,请求钉钉的时候使用的是https的方式。所以一开始没有怀疑这个脚本,这个时候尝试把对应的定时任务关了,结果上面那个脚本显示的结果真的不增加了,看来真的是这个脚本的锅…
这个时候感觉好奇怪,钉钉上也灭有啥信息啊,不可能每分钟都发信息啊。手动运行了一下脚本,发现发送钉钉之后返回的错误码显示是消息格式有问题,所以不会显示,又因为没有发送成功就会每隔一分钟发送一次。。。,因为是一个过时的监控,所以一直没有注意过,结果埋了一个坑。。

  到此,谜底才真正解开,舒服多了,总结一下就是自己写的一个监控脚本有bug,正好触发了curl请求的一个底层bug,导致内核取dentry的分配消耗很大,

2.4.2 curl请求bug的发现

上面的排查过程说明了curl请求的锅,这里聊一下自己验证curl请求的锅的时候使用的脚本。
** 1. 大量发送curl请求的脚本 **
有些时候请求量小的话不太容易看出来

/bin/egrep 'Slab|claim' /proc/meminfo ; /usr/bin/slabtop -o | /bin/egrep 'Slab|SLAB|dent' ; /bin/sh -c 'for i in `seq 300`; do echo -e ".\c" ; /usr/bin/curl --silent https://www.baidu.com > /dev/null  ;done ';echo -e "\n" ; /usr/bin/slabtop -o | /bin/egrep 'Slab|SLAB|dent' ;  /bin/egrep 'Slab|claim' /proc/meminfo
Slab:            2327552 kB
SReclaimable:    2274480 kB
SUnreclaim:        53072 kBActive / Total Slabs (% used)      : 577915 / 578012 (100.0%)OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME
7297080 7280735  99%    0.19K 364854       20   1459416K dentry
............................................................................................................................................................................................................................................................................................................Active / Total Slabs (% used)      : 581810 / 581956 (100.0%)OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME
7365320 7365320 100%    0.19K 368266       20   1473064K dentry
Slab:            2344412 kB
SReclaimable:    2288276 kB
SUnreclaim:        56136 kB

  测试中发现这个不一定每次都会大量增加,可能因为某些时间点的回收导致的,但是如果是量足够大的话,比如上万次,肯定会增加的比较大。
同时,我们还可以辅助用一个脚本来判断。

** 2. 跟踪dentry分配的细节 **
为了确认有dentry分配,当然,我们可以使用上面的那个跟踪d_alloc的脚本实现,还有一种是可以跟踪dentry具体对应的目录,当然,还是使用强大的systemTap

cat detail_dentry.stpprobe kernel.function("dentry_lru_add")
{printf("%s - %s - tid: %d, pid: %ld , ppid: %d, path: /%s\n",tz_ctime(gettimeofday_s()), execname(),tid(),pid(), ppid(),reverse_path_walk($dentry))
}

使用 stap detail_dentry.stp > d05.log &来进行记录
然后查看对应文件的记录数据。

head  d05.logFri Oct 11 12:15:02 2019 CST - curl - tid: 30581, pid: 30581 , ppid: 30217, path: /etc/pki/nssdb/.3851895983_dOeSnotExist_.db
Fri Oct 11 12:15:02 2019 CST - curl - tid: 30581, pid: 30581 , ppid: 30217, path: /etc/pki/nssdb/.3851895984_dOeSnotExist_.db
Fri Oct 11 12:15:02 2019 CST - curl - tid: 30581, pid: 30581 , ppid: 30217, path: /etc/pki/nssdb/.3851895985_dOeSnotExist_.db
Fri Oct 11 12:15:02 2019 CST - curl - tid: 30581, pid: 30581 , ppid: 30217, path: /etc/pki/nssdb/.3851895986_dOeSnotExist_.db
Fri Oct 11 12:15:02 2019 CST - curl - tid: 30581, pid: 30581 , ppid: 30217, path: /etc/pki/nssdb/.3851895987_dOeSnotExist_.db
Fri Oct 11 12:15:02 2019 CST - curl - tid: 30581, pid: 30581 , ppid: 30217, path: /etc/pki/nssdb/.3851895988_dOeSnotExist_.db
Fri Oct 11 12:15:02 2019 CST - curl - tid: 30581, pid: 30581 , ppid: 30217, path: /etc/pki/nssdb/.3851895989_dOeSnotExist_.db
Fri Oct 11 12:15:02 2019 CST - curl - tid: 30581, pid: 30581 , ppid: 30217, path: /etc/pki/nssdb/.3851895990_dOeSnotExist_.db
Fri Oct 11 12:15:02 2019 CST - curl - tid: 30581, pid: 30581 , ppid: 30217, path: /etc/pki/nssdb/.3851895991_dOeSnotExist_.db
Fri Oct 11 12:15:02 2019 CST - curl - tid: 30581, pid: 30581 , ppid: 30217, path: /etc/pki/nssdb/.3851895992_dOeSnotExist_.db

根据对应的 ** /etc/pki/nssdb/.3851895989_dOeSnotExist_.db** 关键字也能够google出对应的bug来。

这个bug对应的记录在这里
从这里综合的信息来看,这个bug描述来看,好像是nss的一个bug,出现在3.14.3-4.el6_4.x86_64,如果想要彻底修复,需要经NSS 升级到3.16.1-4
但是实际上在低一些的版本也提供了修复方案,只有是版本大于等于nss-softokn-3.14.3-12.el6 即可通过设置一个变量 export NSS_SDB_USE_CACHE=yes来解决
查看本机的版本

curl --version
curl 7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.27.1 zlib/1.2.3 libidn/1.18 libssh2/1.4.2yum list nss-softokn
...
Installed Packages
nss-softokn.x86_64                                                     3.14.3-23.el6_7                                                       @anaconda-CentOS-201605220104.x86_64/6.8
...

可以看到本机是nss-softokn 版本是3.14.3-23.el6_7 属于bug修复的版本,但不是终极修复版本。
通过在监控脚本的开头添加

export NSS_SDB_USE_CACHE=yes

最终解决问题。

3 . 数据样例附

cat log_slab.log
time                       slab-kb     dentry-kb      diff
2019.10.09-21:01:19        2929348      2685424       243924
2019.10.09-21:01:28        2929204      2685424       243780
2019.10.09-21:01:30        2928804      2685424       243380
2019.10.09-21:01:31        2928736      2685424       243312
2019.10.09-21:06:01        2935132      2691656       243476
#log_file="/home/deploy/search/test_data/systemtap_dependency/dentry_record_/log_slab.log"
log_file="$(cd $(dirname $0);pwd)/log_slab.log"
echo "$log_file"
if [ ! -e $log_file ] ;thenecho "not exist"echo "2019.10.09-21:01:19        2929348      2685424       243924" > $log_filefi
dentry_size=$( /usr/bin/slabtop -o|grep dentry |awk '{print $7}'|sed -e "s/K//g")
slab_size=$( cat /proc/meminfo | grep Slab|awk  '{print $2}')
cur_time=$(date +'%Y.%m.%d-%H:%M:%S')
diff_s_d=$(echo "${slab_size}-${dentry_size}"|bc)lastest_dentry=$(tail -n1 ${log_file}|awk '{print $3}')
diff_dentry=$(echo "${dentry_size} - ${lastest_dentry}"|bc)res="${cur_time}        ${slab_size}      ${dentry_size}       ${diff_s_d}      ${diff_dentry}"
#echo "$res" >> /home/deploy/search/test_data/systemtap_dependency/dentry_record_/log_slab.log
echo "$res" >> ${log_file}

参考

感谢大家分享,让我得以查到这个问题

https://blog.csdn.net/mans1516/article/details/51434408
https://zhuanlan.zhihu.com/p/43133085
https://blog.arstercz.com/centos-%E7%B3%BB%E7%BB%9F-slab-dentry-%E8%BF%87%E9%AB%98%E5%BC%95%E8%B5%B7%E7%B3%BB%E7%BB%9F%E5%8D%A1%E9%A1%BF%E5%88%86%E6%9E%90%E5%A4%84%E7%90%86/

free和top显示可用内存不一致相关推荐

  1. 【linux】free和top显示可用内存不一致|free显示内存90%但是top却看不到谁用

    free和top显示可用内存不一致 free可用内存偏少是top相对free没有统计Slab.这也是导致两者差别的主要原因. 可以使用 cat /proc/meminfo看到内存的更具体的使用情况 以 ...

  2. 已安装内存和可用内存不一致 4GB内存在win1064位系统中显示为可用 3.87GB解决办法

    问题如图:64位系统已经安装了4G内存,却在括号内显示3.87GB可用? 正常情况下如图:仅显示已安装的内存为8G,后面没有括号提示! 实际分析: 排除硬件保留内存寻址可能 Windows 将部分内存 ...

  3. 台式计算机的8g,win10系统台式机配置8G内存显示可用内存只有3.4G的教程

    win10系统使用久了,好多网友反馈说win10系统台式机配置8G内存显示可用内存只有3.4G的问题,非常不方便.有什么办法可以永久解决win10系统台式机配置8G内存显示可用内存只有3.4G的问题, ...

  4. 计算机专业8g内存,win7系统台式机8G内存但是显示可用内存只有3.4G如何解决

    有用户在购买台式机安装win7系统,发现明明电脑配置的是8G内存,但是打开计算机属性发现可用内存只有3.4G,遇到这样的问题该怎么办呢,下面给大家分享一下win7系统台式机8G内存但是显示可用内存只有 ...

  5. 在64位总线下,安装了8G内存条,却显示可用内存不到8G的原因

    1.查看可用内存的指令: cat /proc/meminfo |grep MemTotal 2.原因:Intel官方称:当内存条容量不小于4GB时,集成显卡会占用部分内存.

  6. Ajax(一)显示可用内存空间

    打开VS,新建空网站,添加新项命名为Receive.aspx<br> 在后台的内容为:  protected void Page_Load(object sender, EventArgs ...

  7. 服务器装了16g内存只显示4g,主板说最大支持8G内存但是我插上了4条4G的,在电脑里能显示可用内存16G,这个是为什么?...

    这个是正常的,而且没有任何水分或问题的. 为什么你的主板参数上写最大支持8G,但是你插上16G都可用呢? 这个原因,是由当时内存条生产现状决定的. 比如你这块板子,有4个内存槽,在当时设计生产这个板子 ...

  8. 新增内存条后,已安装内存和可用内存不一致(win7)

    做个备忘: 刚装了一个8G的内存条,发现已安装内存和内存总数不一样,已安装内存为16G,但是总数还是原来的8G没变 后来发现还是需要设置一下: win+r 后输入 msconfig 重启后就出现已安装 ...

  9. 计算机可用内存分配失败,安装内存和实际可用内存不一样什么原因

    通常我们安装内存条时候都有显示具体内存,但是有时出现安装内存和实际可用内存不一致?为什么会不一样呢?下面我们一起来看看其中的原因和解决方法. 一.你安装的不是64位Win7系统 Win7 32位只能识 ...

最新文章

  1. 10亿美元续命!OpenAI获微软投资,意在通用人工智能?
  2. 宠粉福利,100G网盘最新架构技术资料合集限时领
  3. Android SlidingMenu 开源项目 侧拉菜单的使用(详细配置)
  4. 利用license机制来保护Java软件产品的安全
  5. bootstrap时间控件
  6. CLR运行时细节 - 继承多态的实现
  7. 西部数码域名解析到阿里云_西部数码云主机好吗 稳定性如何
  8. iso qemu 安装ubuntu_qemu 安装 ubuntu-server 虚拟机
  9. 正则表达式的学习使用
  10. csgo开发者控制台指令大全_csgo控制台指令大全 csgo控制台命令一览
  11. 淘宝商品描述信息查询API接口(淘宝商品详情API接口)
  12. 湖仓一体在金融科技行业的实践
  13. 对应win10的服务器系统,我的系统变成win10远程服务器系统
  14. 零成本搭建实验室、课题组网站教程(基于uniapp)
  15. linux中如何看文件换行符,linux下的换行符
  16. 各种“地”—— 各种“GND”
  17. pythoncad二次开发视频_pycad学习笔记(一)
  18. 用静态KML脚本在GoogleEarth上实现动态效果
  19. HTTP常见请求头/响应头
  20. 「力扣数据库」183. 从不订购的客户(第五天)

热门文章

  1. 【玩转cocos2d-x之七】场景类CCScene和布景类CCLayer
  2. PyCairo 中的图片
  3. python中的with上下文管理器
  4. 服务器性能优化之网络性能优化
  5. 微服务下分布式事务模式的详细对比
  6. 从Java角度看Golang
  7. 动画图解 socket 缓冲区的那些事儿
  8. 2022 WebRTC发展趋势分析
  9. FFmpeg深度学习模块的历史、现状和计划
  10. 5G时代探索互动立体视频信息承载的新可能