使用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
具体如何判断回收次数,空间等等后续介绍