通过jstack与jmap分析一次线上故障

一、发现问题

  下面是线上机器的cpu使用率,可以看到从4月8日开始,随着时间cpu使用率在逐步增高,最终使用率达到100%导致线上服务不可用,后面重启了机器后恢复。

二、排查思路 

简单分析下可能出问题的地方,分为5个方向:

1.系统本身代码问题

2.内部下游系统的问题导致的雪崩效应

3.上游系统调用量突增

4.http请求第三方的问题

5.机器本身的问题

三、开始排查 

1.查看日志,没有发现集中的错误日志,初步排除代码逻辑处理错误。

2.首先联系了内部下游系统观察了他们的监控,发现一起正常。可以排除下游系统故障对我们的影响。

3.查看provider接口的调用量,对比7天没有突增,排除业务方调用量的问题。

4.查看tcp监控,TCP状态正常,可以排除是http请求第三方超时带来的问题。

5.查看机器监控,6台机器cpu都在上升,每个机器情况一样。排除机器故障问题。

  即通过上述方法没有直接定位到问题。

四、解决方案

1.重启了6台中问题比较严重的5台机器,先恢复业务。保留一台现场,用来分析问题。

2.查看当前的tomcat线程pid

3.查看该pid下线程对应的系统占用情况。top -Hp 384

4.发现pid 4430 4431 4432 4433 线程分别占用了约40%的cpu

5.将这几个pid转为16进制,分别为114e 114f 1150 1151

6.下载当前的java线程栈  sudo -u tomcat jstack -l 384>/1.txt

7.查询5中对应的线程情况,发现都是gc线程导致的

8.dump java堆数据

sudo -u tomcat jmap -dump:live,format=b,file=/dump201612271310.dat 384

9.使用MAT加载堆文件,可以看到javax.crypto.JceSecurity对象占用了95%的内存空间,初步定位到问题。

MAT下载地址:http://www.eclipse.org/mat/

10.查看类的引用树,看到BouncyCastleProvider对象持有过多。即我们代码中对该对象的处理方式是错误的,定位到问题。

 

五、代码分析

我们代码中有一块是这样写的

这是加解密的功能,每次运行加解密都会new一个BouncyCastleProvider对象,放倒Cipher.getInstance()方法中。

看下Cipher.getInstance()的实现,这是jdk的底层代码实现,追踪到JceSecurity类中

verifyingProviders每次put后都会remove,verificationResults只会put,不会remove.

看到verificationResults是一个static的map,即属于JceSecurity类的。

所以每次运行到加解密都会向这个map put一个对象,而这个map属于类的维度,所以不会被GC回收。这就导致了大量的new的对象不被回收。

六、代码改进

将有问题的对象置为static,每个类持有一个,不会多次新建。

七、本文总结

遇到线上问题不要慌,首先确认排查问题的思路:

  1. 查看日志
  2. 查看CPU情况
  3. 查看TCP情况
  4. 查看java线程,jstack
  5. 查看java堆,jmap
  6. 通过MAT分析堆文件,寻找无法被回收的对象

 

转载于:https://www.cnblogs.com/kingszelda/p/9034191.html

发布了0 篇原创文章 · 获赞 16 · 访问量 5万+
展开阅读全文
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符

【java】jmap -histo pid 输出的[B 占用很高,请问问题会在哪里?

04-26

公司目前的程序是解析excel表格内容,使用到了poi sax方式解析,但是在监控的过程中发现堆内存B的占用非常高,使用mat工具也告诉B可能存在内存泄漏问题。 代码中那些操作会导致这个问题呢?代码中只使用了一个inputstream来保存文件,而且使用后也关闭了 是在找不到,但是B占了相当多的空间 b就是byte数据(下面这个不是我的图,是我找的一个例图,就是B那个地方,我这里显示的是占用最高的,我不知道我的程序哪里写错了会导致这种情况) ``` num #instances #bytes class name ---------------------------------------------- 1: 1169837 131659368 [C 2: 25945 38337824 [I 3: 31548 29407968 [B 4: 1164546 27949104 java.lang.String 6: 91313 12829072 <constMethodKlass> 7: 12395 12404880 [S 8: 91313 11700288 <methodKlass> 9: 7525 9303112 <constantPoolKlass> 10: 7525 5606808 <instanceKlassKlass> 11: 6043 5028288 <constantPoolCacheKlass> 12: 10048 2007888 [Ljava.lang.Object; 14: 3507 1707048 <methodDataKlass> 15: 8132 980616 java.lang.Class 16: 26854 859328 java.util.HashMap$Entry 17: 12368 699296 [[I 18: 14135 452320 java.util.concurrent.ConcurrentHashMap$HashEntry 19: 20883 334128 java.lang.Object 20: 590 316240 <objArrayKlassKlass> 21: 1757 305904 [Ljava.util.HashMap$Entry; 22: 2809 224720 net.sf.ehcache.Element 23: 1992 223104 java.net.SocksSocketImpl 24: 2668 213440 java.lang.reflect.Method 26: 5932 183928 [Ljava.lang.String; 27: 7588 182112 java.util.concurrent.ConcurrentSkipListMap$Node 28: 7317 175608 java.lang.Long 29: 5303 169696 java.util.Hashtable$Entry 30: 6778 162672 java.util.ArrayList 31: 3931 157240 java.lang.ref.SoftReference 32: 2972 118880 java.util.LinkedHashMap$Entry 33: 1565 112680 org.apache.commons.pool2.impl.DefaultPooledObject 34: 2817 112680 net.sf.ehcache.store.chm.SelectableConcurrentHashMap$HashEntry 35: 2243 107664 java.util.HashMap 36: 2592 103680 java.util.TreeMap$Entry 37: 3214 102848 java.lang.ref.WeakReference 38: 1565 100160 redis.clients.jedis.Client 39: 4155 99720 java.util.LinkedList$Node 40: 1986 95328 java.net.SocketInputStream 41: 414 92952 [Ljava.util.concurrent.ConcurrentHashMap$HashEntry; 42: 2275 91000 java.lang.ref.Finalizer 43: 1161 83592 java.lang.reflect.Constructor 44: 757 78728 java.io.ObjectStreamClass 45: 1587 76176 java.net.SocketOutputStream 46: 1189 66584 java.beans.MethodDescriptor 47: 2770 66480 org.apache.commons.pool2.impl.LinkedBlockingDeque$Node 48: 388 66368 [Ljava.util.Hashtable$Entry; 49: 1989 63648 java.net.Socket 50: 749 53928 java.lang.reflect.Field ... ... 2947: 1 16 sun.misc.Launcher 2948: 1 16 org.codehaus.jackson.map.ser.std.DateSerializer 2949: 1 16 org.apache.phoenix.schema.types.PDataType$2 2950: 1 16 org.springframework.data.redis.connection.convert.StringToRedisClientInfoConverter Total 3090439 316004152 ``` 问答

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览