dkm
作者dkm·2011-10-18 10:51
软件架构设计师·广州八斗软件科技有限公司

Websphere性能优化——面向切面分析Javacore

字数 3883阅读 8422评论 2赞 10

如何更深入地进行系统性能分析与优化呢?

 

一般情况下,我们会通过调整参数来提高系统性能,如线程池大小、连接池大小或者ORB池等,也可以利用IHS实现静态文件分离,以上方式都是通过配置调整,利用并行或压力分离等方式实现对系统的优化。我们还可以更换运算率更高的服务器,或者增加更多的物理服务器,通过硬件角度扩展达到性能调优的目的,但这种硬件扩容调优方式会使得项目的成本费用会大大增加,且优化成效还不一定能达到期待值。当然,在以数据库操作为主的业务系统还可以调整数据库的参数,例如内存占用比率,增加命中,缓冲等的优化。

 

但以上这些优化方式都是从系统周边环境的角度进行考虑的,如果我们不了解我们的业务应用代码在JVM中是如何运行的,又或者各执行的请求是如何进行处理的,其处理的过程及处理步骤处于什么状态下,就盲目开展优化工作,就有了点瞎子过河——摸不着边的意思了。

 

因此,尽可能收集更多的信息,会让我们的优化工作事半功倍!

除了自己实现线程请求监控记录外,我们还可以通过Javacore文件来进行线程转储。通过采集和分析Javacore,了解JVM的运行情况,可以使我们更清晰地了解系统的整体运行情况,帮助我们判断系统是否运行正常,或是在繁忙时存在哪些隐患。

 

一、什么是Javacore

JavacoreJava应用程序在某一时间的文本表示形式,也可理解为Java Dump(通常称为Thread Dump)的线程转储文件。该文件记录了整个JVM的运行情况,包含线程、垃圾回收、JVM运行参数、内存地址等信息。JVM的许多问题都可以用这个文件进行诊断,其中比较典型的包括线程阻塞、CPU使用率过高、JVM Crash、堆内存不足和类装载等问题。

Javacore文件通常以*.txt方式显示,名称格式主要是以Javacore为头,加上日期号、产生的时间号、当时的线程编号,如: Javacore.20100719.003424.299228.txt.

我们可以通过以下几种方式获取Javacore

1.   向操作系统发送一个中止的signal

Ø  AIXLinuxSIGQUITkill 3 PID

Ø  WindowsCTRLBreakDrAdmin in WAS环境

2.   Java的执行代码中使用JavaDump()方法

com.ibm.jvm.Dump.JavaDump() 方法促使JVM dump

 发布ProblemDiagnosticsLabToolkit应用包,通过可视化页面直接生成相关文件。

3.   系统在异常时自动抛出

Ø  一个严重的本地调用出错(非Java的异常)

Ø  JVM堆的大小被使用完了

Ø  OutOfMemory 错误

 

二、Javacore描述了什么内容?

Javacore文件的帮助下,我们就可以更好地分析系统运行情况,在系统出现死锁,或者内部错误、中间件等问题时,我们都可以通过Javacore进一步深入分析。我们可以在Javacore文件里找到以下相关信息:

Ø  JVM的参数启动参数、Jdk版本

Ø  JVM堆大小

Ø  JVM产生原因、产生时间(可手动获取,可系统抛出)

Ø  全局垃圾回收次数、分配失败次数、内存溢出时,最后一次详细的垃圾回收记录

Ø  JVM堆内存地址信息

Ø  JVM中,所有线程执行情况(包含应用程序内部执行线程,容器线程,垃圾回收线程,定时线程,线程池线程,页面请求转发线程等多种线程信息)

Ø  已装载入JVM中的类的信息

如下表:

序号

描述

例子

1

Ø  JAVA产生的原因

Ø  产生时间

Ø  产生的线程号

Ø  JDK版本

Ø  JVM堆大小

Ø  空间堆大小

Ø  已分配的堆大小

 

2

JVM堆对象占用比例信息

3

整体线程的状态,各占比例情况

4

主要线程类型与其线程数,及在整个容器中所占用的比例

5

其他相关信息

……

 

三、如何分析Javacore

我们可以通过Javacore提供的信息对JVM进行一个全面的分析,除了了解垃圾回收情况、JVM相关配置信息外,分析重点可放在线程执行情况上,分析哪些线程在等待,哪些在执行,以便快速缩小问题范围。

(打开Javacore文件,庞大的字符串使得我们查找信息十分不便,此时我们可以利用IBM Thread and Monitor Dump Analyzer for Java工具分析,该工具可以让我们清晰的分析Javacore文件)。

 

 

 

 

IBM Thread and Monitor Dump Analyzer for Java工具中,请求线程可分为以下几种状态:

Ø  死锁,Deadlock(重点关注) 

Ø  执行中,Runnable(重点关注)   

Ø  等待资源,Waiting on condition(重点关注) 

Ø  等待监控器检查资源,Waiting on monitor

Ø  暂停,Suspended

Ø  对象等待中,Object.wait()

Ø  阻塞,Blocked(重点关注)  

Ø  停止,Parked

 

在整个分析过程中,我们需要根据问题分析线程的运行的情况(如该Javacore是什么时候生成的,是内存溢出,还是系统繁忙时),查看不同状态的线程的执行堆栈,分析堆栈找到其中属于系统应用的代码可进一步缩小问题点(在版本稳定的中间件里,我们分析问题一般先从应用代码入手,了解是哪些业务代码触发了问题)。我们要了解线程状态具体的意思,线程中的堆栈代码,整个容器的各个类型线程的情况,结合这些信息进行深入的分析。

 

ü  Deadlock:死锁线程,一般指多个线程调用间,进入相互资源占用,导致一直等待无法释放的情况。

ü  Runnable:一般指该线程正在执行状态中,该线程占用了资源,正在处理某个请求,有可能正在传递SQL到数据库执行,有可能在对某个文件操作,有可能进行数据类型等转换。

ü  Waiting on condition:等待资源,如果堆栈信息明确是应用代码,则证明该线程正在等待资源,一般是大量读取某资源,且该资源采用了资源锁的情况下,线程进入等待状态,等待资源的读取。又或者,正在等待其他线程的执行等。

ü  Blocked:线程阻塞,是指当前线程执行过程中,所需要的资源长时间等待却一直未能获取到,被容器的线程管理器标识为阻塞状态,可以理解为等待资源超时的线程。这种情况在was的日志中,一般可以看到CPU饥渴,或者某线程已执行了XX秒的信息。

 

在了解了以上线程状态的具体意思后,我们就可以结合这些信息更进一步分析线程问题。

 

在内存溢出时,分析Javacore文件中的线程内容,可以采用自下而上的分析方法。首先查看有多少线程被设置了Blocked状态,这些线程是在执行什么请求,并且到了堆栈最后一步在等待什么资源,将其分类记录下来;查找到这些Blocked线程等待的执行线程编号,在Javacore中,继续查找该线程,分析其堆栈与状态与监控器的记录的信息。一般这些线程会处于Waiting on condition状态,因为这些线程也是因为资源迟迟未获取到或者执行时间过长一直处于等待状体,进一步导致队列中其他需要访问这些资源的线程都被设置为Blocked状态。在找到线程后,我们就可以初步将问题缩小到哪些业务应用请求存在问题,是哪一个类与哪一行代码,其等待的资源是什么。结合这些信息详细分析业务代码,或者根据这些问题到IBM网站中,查找对应版本的中间件是否存在同样的问题,如有,则可以考虑打补丁升级。

 

一个Javacore描述的是在一个时间片段中的JVM的运行情况,这些信息相对来说是有限的,为了更进一步分析与定位问题,我们可以采集连续多个时间片段的Javacore,如间隔30秒或者几分钟的Javacore。分别对这些Javacore进行分析,以求更加清晰JVM在该时间段内的运行情况,或者出现阻塞问题的线程及其相关线程的的执行情况,从而准确定位问题。

 

在整个性能优化过程中,学会如何分析Javacore是十分关键的一步。通过切面,对JVM中所运行的线程及堆栈进行全面分析,可以让我们顺利而有方向性地开展性能调优工作,并使优化工作更加简单快捷。

如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!

10

添加新评论2 条评论

杜思杜思研发工程师YY Tech
2016-11-26 22:11
niubility
上进的老恐龙上进的老恐龙软件架构设计师中威科技
2013-08-14 08:53
说的很不错,学习了
Ctrl+Enter 发表

作者其他文章

相关文章

相关问题

相关资料

X社区推广