1 引言

1.1 编写目的

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

1.2编写背景

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

2 分析步骤

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

2.1检查nginx的网络情况

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

2.2检查tomcat 的网络情况

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

3 分析JVM内存溢出

3.1为什么会发生内存泄漏

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

3.2快速定位问题

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

3.2.1 jstack

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

sudo jstack -F 进程ID

输出内容如下:

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

3.2.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的日志所以不确定JVMGC 时间过长,导致应用暂停.

3.2.3获取内存快照

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

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

file:保存路径及文件名

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

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

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

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

3.2.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假死的原因.

4 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 表示被动关

java 进程假死原因_分析java进程假死状况相关推荐

  1. 【源码+图片素材】Java王者荣耀游戏开发_开发Java游戏项目【王者荣耀】1天搞定!!!腾讯游戏_Java课程设计_Java实战项目_Java初级项目

    王者荣耀是当下热门手游之一,小伙伴们是否想过如何制作一款属于自己的王者荣耀游戏呢? 本课程讲解了一个王者荣耀游戏的详细编写流程,即使你是刚入门Java的新手,只要你简单掌握了该游戏所需要的JavaSE ...

  2. java服务器崩溃的原因_请求大神帮忙分析一下服务器崩溃原因

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 ---- Minecraft Crash Report ---- // Who set us up the TNT? Time: 14-6-11 上午12 ...

  3. java 转储快照分析_分析Java核心转储

    java 转储快照分析 在本文中,我将向您展示如何调试Java核心文件,以查看导致JVM崩溃的原因. 我将使用在上一篇文章: 生成Java Core Dump中生成的核心文件. 您可以通过以下几种方法 ...

  4. java 快死了_如果Java快死了,那么它肯定看起来非常健康

    java 快死了 Java快要死了的奇怪但流行的断言只能在没有证据的情况下提出,而不是因为它. 在酷孩子闲逛的论坛(Hacker News,Reddit等)中反复出现的偏见与Java语言背道而驰. 人 ...

  5. java 类文件分析_分析Java .class文件

    这章的一个例子虽然简单,但是我觉的很有一定代表性.例子如下: 1:class Act { 2:   public static void doMathForever(int m) { 3:      ...

  6. java计分系统编程代码_使用Java代码对实时系统进行编程

    由于许多重要原因,Java语言在实时系统中的使用并不广泛. 这些包括Java语言设计固有的不确定性性能影响,例如动态类加载,以及Java Runtime Environment(JRE)本身,例如垃圾 ...

  7. java 中文域名转码_转换java对象

    数据解析 ●网络解析 Gson (一个Java序列化/反序列化库,可以将JSON和java对象互相转换) Jackson (Jackson可以轻松地将Java对象转换成json对象和xml文档,同样也 ...

  8. java字符串拆分成数组_用Java实现JVM第八章《数组和字符串》

    小傅哥 | https://bugstack.cn 沉淀.分享.成长,专注于原创专题案例,以最易学习编程的方式分享知识,让自己和他人都能有所收获.目前已完成的专题有:Netty4.x实战专题案例.用J ...

  9. java 取栈顶元素_《Java实战之内存模型》详解篇

    内存是非常重要的系统资源,是硬盘和CPU的中间仓库及桥梁,承载着操作系统和应用程序的实时运行 JVM内存布局规定了Java在运行过程中内存申请.分配.管理的策略,保证了JVM的高效稳定运行 不同的JV ...

最新文章

  1. SEO优化之meta标签
  2. 2022王道操作系统名词解释概念题
  3. 多线程相互排斥--mutex(二)
  4. 曲曲直直线条图计算机教案,【曲曲直直的美术画】_美术教案第三课:曲曲直直(三年级美术下册教案)——小学美术...
  5. mysql for update场景_一个mysql死锁场景实例分析
  6. 气势汹涌,天津设立千亿级AI基金;刘强东否认会因AI开除一半员工
  7. hadoop程序MapReduce之DataSort
  8. 深度学习 --- 优化入门一(梯度下降所面临的问题)
  9. 传说中Python最难理解的点|看这完篇就够了
  10. jQuery实现锚点滑动定位
  11. Java计算文件MD5值(支持大文件)
  12. python 生成wifi密码字典_python生成密码字典的方法
  13. mhd matlab,应用 | 基于磁流体MHD的FLUENT-Maxwell集成耦合开发
  14. ios开发-教程选择
  15. 教你配置赏心悦目的开发神器 Atom-郭永峰-专题视频课程
  16. 史玉柱的“圈钱”神话3
  17. Point-Set Topological Spatial Relations 点集拓扑空间关系
  18. wordpress 背景_如何为您的WordPress网站找到美丽的背景图像
  19. IDEA怎么使折叠合并的文件夹分开
  20. 计算机毕业设计系列基于SSM的个人博客管理系统

热门文章

  1. addEventListener()使用方法
  2. NP=P,一种解决方案
  3. word论文排版和写作06:审阅和修改文章
  4. Windows 11 电脑如何设置自动开机 (Windows 11 2022H2)
  5. 三星笔记本bios设置里找不到U盘启动盘的解决方法
  6. 嵌入式硬件构件与底层驱动构件基本规范
  7. 南卡和三星哪款蓝牙耳机音质好些?高颜值且音质好的蓝牙耳机测评
  8. iOS 性能监控(一)—— CPU功耗监控
  9. 计算机组成原理经典复习题集锦(附答案)
  10. 配置静态路由——默认路由