linux 内存 buff/cache过高解决方案

使用top命令看下内存情况

本来内存就32G,可以看到buff/cache就占了12G

buff/cache:
Linux具有先进的缓存机制,会针对会针对dentry(用于VFS,加速文件路径名到inode的转换)、Buffer Cache(针对磁盘块的读     写)和Page Cache(针对文件inode的读写)进行缓存操作用来提高读写效率。但是在进行了大量文件操作之后,缓存会把内存资源   基本用光,虽然文件    读取效率提高了,但是物理内存会逐渐被吃光。

然来是因为服务进行了频繁的文件读写操作,但是为什么操作系统不会主动回收呢,原来是因为drop_caches的默认参数设置的就是不释放的
 drop_caches的值可以是0-3之间的数字,代表不同的含义:
 0:不释放(系统默认值)
 1:释放页缓存
 2:释放dentries和inodes
 3:释放所有缓存


第一种方式:缓存立马释放
cd /proc/sys/vm
echo 1 > drop_caches

释放之后需要重新设置为0,不然没有使用到缓存,数据一直都在IO,导致处理慢,设置的方法是重启服务,会自动设置成默认0

第二种方式:重启ECS服务,会自动释放缓存


内存高原因分析
上面图中可以看到某个java程序出现内存占了整个内存的32%(相当于占用了10个G内存),出现这种情况我们一定要引起重视。
1、使用jmap查看Java进程对象使用情况
命令格式:jmap -histo 进程id
jmap -histo 27267 > 1.txt    --将对象使用情况写入到1.txt文件中,然后下载下来,截取了前30行,如下所示:

 num     #instances         #bytes  class name
----------------------------------------------
   1:      14759056     1416869376  org.apache.xmlbeans.impl.store.Xobj$AttrXobj
   2:      31708671     1379128112  [C
   3:      10396772      998090112  org.apache.xmlbeans.impl.store.Xobj$ElementXobj
   4:      12826246      810404432  [I
   5:      26817009      643608216  java.lang.String
   6:      16110427      515533664  java.util.HashMap$Node
   7:       6013856      384886784  java.util.regex.Matcher
   8:       6653042      266121680  java.util.LinkedHashMap$Entry
   9:        141214      261393704  [B
  10:       4941211      197648440  java.util.TreeMap$Entry
  11:       4919274      196770960  org.apache.xmlbeans.impl.values.XmlUnsignedIntImpl
  12:       1725454      181109384  [Ljava.util.HashMap$Node;
  13:       4372726      139927232  org.openxmlformats.schemas.spreadsheetml.x2006.main.impl.STXstringImpl
  14:       4372704      139926528  org.apache.poi.xssf.usermodel.XSSFCell
  15:       4372704      139926528  org.openxmlformats.schemas.spreadsheetml.x2006.main.impl.STCellRefImpl
  16:       4372691      139926112  org.openxmlformats.schemas.spreadsheetml.x2006.main.impl.STCellTypeImpl
  17:       4372704      104944896  org.openxmlformats.schemas.spreadsheetml.x2006.main.impl.CTCellImpl
  18:       1151263       55260624  java.util.HashMap
  19:       2788857       44621712  java.lang.Integer
  20:        280566       36357864  [Ljava.lang.Object;
  21:        550804       35251456  org.springframework.util.LinkedCaseInsensitiveMap$1
  22:       1345674       32296176  java.lang.StringBuffer
  23:        550966       26446368  java.util.TreeMap
  24:        550804       22032160  org.springframework.util.LinkedCaseInsensitiveMap
  25:        546594       17491008  org.apache.xmlbeans.impl.values.XmlDoubleImpl
  26:        567495       13619880  java.lang.Long
  27:        552016       13248384  org.openxmlformats.schemas.spreadsheetml.x2006.main.impl.CTRstImpl
  28:        546596       13118304  org.apache.xmlbeans.impl.values.XmlBooleanImpl
  29:        546588       13118112  org.apache.poi.xssf.usermodel.XSSFRow
  30:        546588       13118112  org.openxmlformats.schemas.spreadsheetml.x2006.main.impl.CTRowImpl

列明说明:
第一列,序号
第二列,对象实例数量
第三列,对象实例占用总内存数。单位:字节
第四列,对象实例名称

可以看出前几个吃内存的都跟java中excel导出报表POI有关系,如下:
org.apache.xmlbeans.impl.store.Xobj$AttrXobj
org.apache.xmlbeans.impl.store.Xobj$ElementXobj
[C
[I
[B
org.apache.xmlbeans.impl.values.XmlUnsignedIntImpl
 org.openxmlformats.schemas.spreadsheetml.x2006.main.impl.STXstringImpl
org.apache.poi.xssf.usermodel.XSSFCell
org.openxmlformats.schemas.spreadsheetml.x2006.main.impl.STCellRefImpl
org.openxmlformats.schemas.spreadsheetml.x2006.main.impl.STCellTypeImpl
org.openxmlformats.schemas.spreadsheetml.x2006.main.impl.CTCellImpl
org.apache.xmlbeans.impl.values.XmlBooleanImpl
org.apache.poi.xssf.usermodel.XSSFRow
org.openxmlformats.schemas.spreadsheetml.x2006.main.impl.CTRowImpl

其中
[C 代表char
[I  代表int
[B  代表byte
因为涉及到大量循环,造成创建了很多对象,未释放,可以看到前14行数据已经占用了7个多G内存。

问了开发人员,居然导出27万多行数据,如下所示:

所以本次内存占用高的问题就是导出Excel报表。


2、使用jstat查看Java内存分布及回收情况
命令格式:jstat -gc  27267   5000
即会每5秒实时打印一次显示进程号为27267的java进成的GC情况


每列解释说明:
 

- S0C: Young Generation第一个survivor space的内存大小 (kB).

- S1C: Young Generation第二个survivor space的内存大小 (kB).

- S0U: Young Generation第一个Survivor space当前已使用的内存大小 (kB).

- S1U: Young Generation第二个Survivor space当前已经使用的内存大小 (kB).

- EC: Young Generation中eden space的内存大小 (kB).

- EU: Young Generation中Eden space当前已使用的内存大小 (kB).

- OC: Old Generation的内存大小 (kB).

- OU: Old Generation当前已使用的内存大小 (kB).

- MC: Permanent Generation的内存大小 (kB)

- MU: Permanent Generation当前已使用的内存大小 (kB).

- YGC: 从启动到采样时Young Generation GC的次数

- YGCT: 从启动到采样时Young Generation GC所用的时间 (s).

- FGC: 从启动到采样时Old Generation GC的次数.

- FGCT: 从启动到采样时Old Generation GC所用的时间 (s).

- GCT: 从启动到采样时GC所用的总时间 (s).

可参考地址如下:https://www.cnblogs.com/qmfsun/p/5601734.html

具体如何判断回收次数,空间等等后续介绍

 

  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux 系统中,buff/cache 是操作系统用来缓存磁盘数据的一种机制。当应用程序需要读取磁盘上的数据时,Linux 会先将这些数据缓存到内存中,以提高磁盘读取速度。当应用程序需要使用内存时,缓存数据会被清除,将内存返还给应用程序使用。 如果 buff/cache 内存占用过高,有几种可能的解决办法: 1. 调整 vm.dirty_ratio 和 vm.dirty_background_ratio 参数 vm.dirty_ratio 指定了内存中脏数据所占的最大比例,默认值为 20,意味着当内存中脏数据占用超过 20% 时,系统会开始写入磁盘。vm.dirty_background_ratio 指定了内存中脏数据所占的最小比例,默认值为 10,意味着当内存中脏数据占用低于 10% 时,系统会开始写入磁盘。 可以通过修改这两个参数的值来调整 buff/cache 内存占用。例如,将 vm.dirty_ratio 和 vm.dirty_background_ratio 的值都设置为 5,则系统会更频繁地把脏数据写入磁盘,从而减少内存中的缓存数据。 2. 调整 swappiness 参数 swappiness 是一个控制系统将内存中的数据交换到交换空间的程度的参数。默认值为 60,意味着当内存使用率达到 60% 时,系统会开始把一些数据写入交换空间。可以通过修改 swappiness 的值来调整系统的交换行为,从而影响 buff/cache 内存的占用。 例如,将 swappiness 的值设置为较低的 10,则系统会更倾向于保留内存中的缓存数据,从而减少交换行为,降低 buff/cache 内存占用。 3. 增加物理内存 如果系统中物理内存不足,buff/cache 内存占用就会相对较高。可以通过增加物理内存来减少 buff/cache 内存占用,从而提高系统的性能。 需要注意的是,增加物理内存并不是万能的解决办法,可能存在其他因素导致的 buff/cache 内存占用过高问题。在调整系统参数和增加物理内存之前,需要仔细分析系统的性能瓶颈和内存使用情况,找出问题的根本原因。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值