一.引言

1.编写目的

为了方便大家以后发现进程假死的时候能够正常的分析并且第一时间保留现场快照。

2.编写背景

最近服务器发现tomcat的应用会偶尔出现无法访问的情况。经过一段时间的观察最近又发现有台tomcat的应用出现了无法访问情况。简单描述下该台tomcat当时具体的表现:客户端请求没有响应,查看服务器端tomcat的进程是存活的,查看业务日志的时候发现日志停止没有任何最新的访问日志。连tomcat下面的catalina.log也没有任何访问记录,基本断定该台tomcat已不能提供服务。

二.分析步骤

根据前面我描述的假死现象,我最先想到的是网络是否出现了问题,是不是有什么丢包严重的情况,于是我开始从请求的数据流程开始分析,由于我们业务的架构采用的是nginx+tomcat的集群配置,一个请求上来的流向可以用下图来简单的描述一下:


1.检查nginx的网络情况

更改nginx的配置,让该台nginx请求只转到本机器的出现问题的tomcat应用上面,在access.log里看是否有网络请求,结果可以查看到当前所有的网络请求,也就是说可以排除是网络的问题。

2.检查tomcat 的网络情况

分析业务配置的tomcat访问日志xxxx.log上是否有日志访问记录,经过查询该台tomcat应用日志完全没有任何访问记录,由于我们的部署是本机的nginx转到本机的tomcat应用,所以可以排除不是网络问题。到此基本可以断定网络没有问题,tomcat 本身出现了假死的情况。在tomcat的日志里有报过OutOfMemoryError的异常,所以可以肯定tomcat假死的原因是OOM

三.分析JVM内存溢出

1.为什么会发生内存泄漏

在我们学习Java的时候就知道它最为方便的地方就是我们不需要管理内存的分配和释放,一切由JVM自己来进行处理,当Java对象不再被应用时,等到堆内存不够用时JVM会进行GC处理,清除这些对象占用的堆内存空间,但是如果对象一直被应用,那么JVM是无法对其进行GC处理的,那么我们创建新的对象时,JVM就没有办法从堆中获取足够的内存分配给此对象,这时就会导致OOM。我们出现OOM原因,一般都是因为我们不断的往容器里存放对象,然而容器没有相应的大小限制或清除机制,这样就容易导致OOM。

2.快速定位问题

当我们的应用服务器占用了过多内存的时候,我们怎么样才能快速的定位问题呢?要想快速定位问题,首先我们必需获取服务器JVM某时刻的内存快照。Jdk里面提供了很多相应的命令比如:jstack,jstat,jmap,jps等等. 在出现问题后我们应该快速保留现场。

1).jstack

可以观察到jvm中当前所有线程的运行情况和线程当前状态.

sudo jstack -F 进程ID

输出内容如下:


        从上面的图我们可以看到tomcat进程里面没有死锁的情况,而且每个线程都处理等待的状态。这个时候我们可以telnet命令连上tomcat的端口查看tomcat进程是否有任务回应。这时发现tomcat没有任何回应可以证明tomcat应用已没有响应,处于假死状态。

2)jstat

这是jdk命令中比较重要,也是相当实用的一个命令,可以观察到classloader,compiler,gc相关信息

具体参数如下:

-class:统计class loader行为信息

-compile:统计编译行为信息

-gc:统计jdk gc时heap信息

-gccapacity:统计不同的generations(包括新生区,老年区,permanent区)相应的heap容量情况

-gccause:统计gc的情况,(同-gcutil)和引起gc的事件

-gcnew:统计gc时,新生代的情况

-gcnewcapacity:统计gc时,新生代heap容量

-gcold:统计gc时,老年区的情况

-gcoldcapacity:统计gc时,老年区heap容量

-gcpermcapacity:统计gc时,permanent区heap容量

-gcutil:统计gc时,heap情况

-printcompilation:不知道干什么的,一直没用过。

一般比较常用的几个参数是:

sudo jstat -class 2083 1000 10 (每隔1秒监控一次,一共做10次)

查看当时的head情况

sudo jstat -gcutil  20683 2000


        注:该图不是出错截取

出现时候截取的数据是gc已经完全没有处理了,因为没有加上full gc的日志所以不确定JVM GC 时间过长,导致应用暂停。

3)获取内存快照

Jdk自带的jmap可以获取内在某一时刻的快照

命令:jmap -dump:format=b,file=heap.bin <pid>

file:保存路径及文件名

pid:进程编号(windows通过任务管理器查看,linux通过ps aux查看)

dump文件可以通过MemoryAnalyzer分析查看,网址:http://www.eclipse.org/mat/,可以查看dump时对象数量,内存占用,线程情况等。


        从上面的图可以看得出来对象没有内存溢出。


        从上图我们可以明确的看出此项目的HashMap内存使用率比较高,因为我们的系统都是返回Map的数据结构所以占用比较高的内存是正常情况。

4).观察运行中的jvm物理内存的占用情况

观察运行中的jvm物理内存的占用情况,我们也可以用jmap命令。

参数如下:

-heap:打印jvm heap的情况

-histo:打印jvm heap的直方图。其输出信息包括类名,对象数量,对象占用大小。

-histo:live :同上,但是只答应存活对象的情况

-permstat:打印permanent generation heap情况

命令使用:

jmap -heap 2083

可以观察到New Generation(Eden Space,From Space,To Space),tenured generation,Perm Generation的内存使用情况

输出内容:


        上图为tomcat应用出错前JVM的配置信息,可以明确的看到当时的信息:

MaxHeapSize堆内存大小为:3500M

MaxNewSize新生代内存大小:512M

PermSize永久代内存大小:192M

NewRatio设置年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)。设置为2,则年轻代与年老代所占比值为1:2,年轻代占整个堆栈的1/3。

SurvivorRatio设置年轻代中Eden区与Survivor区的大小比值。设置为8,则两个Survivor区与一个Eden区的比值为2:8,一个Survivor区占整个年轻代的1/10。

在New Generation中,有一个叫Eden的空间,主要是用来存放新生的对象,还有两个Survivor Spaces(from,to), 它们用来存放每次垃圾回收后存活下来的对象。在Old Generation中,主要存放应用程序中生命周期长的内存对象,还有个Permanent Generation,主要用来放JVM自己的反射对象,比如类对象和方法对象等。

从上面的图可以看出来JVM的新生代设置太小,可以看出应用的新生代区完全占满了,无法再往新生代区增加新的对象此时的这些对象都处于活跃状态,所以不会被GC处理,但是tomcat应用还在继续产生新的对象,这样就会导致OOM的发生,这就是导致tomcat假死的原因。

四.Tomcat假死其它情况

以下是网上资料说的tomcat假的情况:

1.应用本身程序的问题,造成死锁。

2.load 太高,已经超出服务的极限。

3.jvm GC 时间过长,导致应用暂停。

因为出错项目里面没有打出GC的处理情况,所以不确定此原因是否也是我项目tomcat假死的原因之一。

4.大量tcp 连接 CLOSE_WAIT

netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
TIME_WAIT 48
CLOSE_WAIT 2228
ESTABLISHED 86

常用的三个状态是:ESTABLISHED 表示正在通信,TIME_WAIT 表示主动关闭,CLOSE_WAIT 表示被动关。

文章来源:http://www.myexception.cn/internet/2044496.html

分析java进程假死相关推荐

  1. java假死_分析java进程假死

    一.引言 1.编写目的 为了方便大家以后发现进程假死的时候能够正常的分析并且第一时间保留现场快照. 2.编写背景 最近服务器发现tomcat的应用会偶尔出现无法访问的情况.经过一段时间的观察最近又发现 ...

  2. java 进程假死原因_分析java进程假死状况

    1 引言 1.1 编写目的 为了方便大家以后发现进程假死的时候能够正常的分析并且第一时间保留现场快照. 1.2编写背景 最近服务器发现tomcat的应用会偶尔出现无法访问的情况.经过一段时间的观察最近 ...

  3. 线上服务Java进程假死快速排查、分析

    线上服务Java进程假死快速排查.分析 最近我们有一台服务器上的Java进程总是在运行个两三天后就无法响应请求了,具体现象如下: 请求业务返回状态码502,查看进程还在,意味着Java进程假死,无法响 ...

  4. java 进程假死原因_Java进程假死案例集合

    1. 案例1 今天通过域名调一个接口,10次中偶尔有1-2次请求失败,域名后绑定VIP,VIP后面为5台应用服务器. 1.1 范围缩小 直觉怀疑为某一台有有问题,于是单独的进行接口调用发现确实为其中一 ...

  5. GC overhead limt exceed 导致的java进程假死

    2019独角兽企业重金招聘Python工程师标准>>> 1.现象 线上后台任务的java进程处于假死状态 2.排查过程 1.查看假死的进程ID ps -ef | grep sku 2 ...

  6. 检查java程序假死的脚本

    http://b.formyz.org/show.php?contentid=55 某站点以java开发,运行在tomcat上,但因某些原因,java时不时假死或者自动停止.为了防止这个问题,临时采取 ...

  7. java服务程序假死(进程存在但请求无响应)的几种原因

    1. 假死现象 服务程序假死具有以下特征: 1. 程序对请求没有任何响应: 2. 程序请求时没有任何日志输出: 3. 程序进程存在,通过jps或者ps查看进程,可以看到服务进程存在: 2. 造成假死的 ...

  8. java程序假死_分析一个常见的java多线程通信问题(假死现象)

    一件复杂的事,一个人如果不能做,两个人又做的不好,一群人就可能很好的解决了.对于线程来说也是,通过多个线程就能完成一个更复杂的功能,这就需要多个线程协作,协作就需要交流,但是交流总是会出问题的.在这篇 ...

  9. java 进程 突然死掉_一次 java 进程猝死的原因分析

    问题 Java进程在服务器中运行一段时间,服务不稳定,偶尔出现进程无故的死亡.临时的办法是重启进程,但过一段时间后又无故死亡.没有任何 jvm oom的错误信息. 路径 1.通过jvm监控查看jvm监 ...

最新文章

  1. bnu 4067 美丽的花环
  2. 软件工程——团队作业3
  3. 性能监控工具javamelody与spring的集成
  4. C++11并发实战(专栏)
  5. 赋能尖端科技 推进智能布局 |《HPC高性能计算数据存储解决方案蓝皮书》正式发布
  6. YOLO V3 原理
  7. Stateflow_after计时计数
  8. c++ extern学习
  9. 5万字、97 张图总结操作系统核心知识点
  10. tl wn322g linux驱动下载,TP-Link TL-WN322G+网卡驱动
  11. 计算机应用软件开机自动启动设置,如何关闭开机自动启动的软件?
  12. 利用javascript写一个石头剪刀布的简易小游戏
  13. 【性能测试之问题分析】遇到内存告警百分之80以上的排查逻辑及实例分析(关键字:JVM、JAVA)
  14. 关于SwiftUI,看这一篇就够了
  15. matlab寻找频谱峰值,matlab – 从数据中获取FFT峰值
  16. CeisumLabApkServe--为CeisumLab工具下载地图,影像数据的.pak文件架设地图服务
  17. MyBatis(3)
  18. 设置vim 显示行号
  19. zepto移动端web相册
  20. 我的PLSQL学习之路-基础

热门文章

  1. 2W10-ASEMI整流圆桥2W10
  2. jQuery(六)插件、Validate验证提交表单、submitHandler、更改错误信息显示的位置、required、Validator、内置验证方式表、validate ()的可选项汇总
  3. N的阶乘末尾有几个零C语言,N的阶乘末尾有多少个零?
  4. 第4-5课:铺瓷砖问题
  5. 生成图片验证码功能(前端+后端)
  6. [ 数据结构-C实现 ] 用堆解决TopK问题
  7. 简单的vim配置+下载好的插件(复制即用!)
  8. python进度条打印
  9. ant design vue table表格组件实现隔行变色
  10. ue4纹理的分辨率_为设计师提供50种高分辨率木材纹理