标签:
Javacore 是一个当前 JVM 运行状态的快照。通过对Javacore 的分析,可以了解在 JVM 中运行的应用程序的当前状态,比如是否“卡”在某一点上,或在某些代码上运行时间太长。
Javacore,也可以称为“threaddump”或是“javadump”,它是 Java 提供的一种诊断特性,能够提供一份可读的当前运行的 JVM 中线程使用情况的快照。即在某个特定时刻,JVM 中有哪些线程在运行,每个线程执行到哪一个类,哪一个方法。
应用程序如果出现不可恢复的错误或是内存泄露,就会自动触发 Javacore 的生成。而为了性能问题诊断的需要,我们也会主动触发生成 Javacore。在 AIX、Linux、Solaris 环境中,我们通常使用 kill -3 <PID> 产生该进程的 Javacore。
对于IBM JVM,AIX 平台上的 Javacore 会被写到 javacore.<date>.<time>.<PID>.<sequence>.txt 中。对于Oracle JVM,Javacore 被附加到native_stdout.txt。
虽然不同版本的 JVM 所产生的 Javacore 的格式会稍有不同,但基本都包含下面几个内容:
TITLE 信息块:描述 Javacore 产生的原因,时间以及文件的路径。最常见的有下面三种:
GPINFO 信息块:GPF(一般保护性错误)信息
ENVINFO 信息块:系统运行时的环境和 JVM 参数
MEMINFO 信息块:内存使用情况和垃圾回收情况
LOCKS 信息块:用户监视器(monitor)和系统监视器(monitor)情况
THREADS 信息块:所有 java 线程的状态信息和执行堆栈
CLASSES 信息块:类加载信息
Javacore 中的线程可分为以下几种状态:
通过对 Javacore 数据的分析经验,结合对具体应用代码逻辑的理解,有经验的工程师可以直接通过文本编辑器查看原始 Javacore 文件来分析当前应用程序的运行状态。一般初学者则需要通过一些工具进行更直观的分析。图形化分析工具 TMDA
不论是否利用 TMDA 工具进行分析,对 Javacore 的分析最终都会落实在具体线程的执行堆栈上。如果对具体应用的代码不熟悉,那么看着一个个长长的执行堆栈,可能会觉得无从下手。本部分介绍 WC 线程执行堆栈的常见代码和对应的功能模块。初学者可以根据这些示例推测某个线程的当前运行状态。需要注意的是,WC 的不同版本,同样的功能模块的具体代码可能会发生变化,经过用户定制的代码就更是千差万别。本部分提供的只是依据 WC FEP7 版本代码的一些示例,读者需要根据自己所处理的系统的实际代码情况灵活掌握,不可拘泥。
通常一个 Javacore 里面会有上百个线程,这些线程的地位并不一样。有些线程是系统运行的“入口线程”,而其他一些线程只是由这些线程派生出来的辅助线程。所以 Javacore 分析过程中一定要抓住这些主要线程。
WC 的核心是一个 Web 应用,所以大部分 WC 的 Javacore 以应用服务器的 Web 容器为入口。用来处理前台商店或后台管理端的 JVM 基本类似,但专门运行定时任务的 JVM 会有所区别。下图 2 所示为以 Web 容器为入口线程的一般调用结构:
从 Web 容器入口开始,一般会进入 Servlet 执行。如果有缓存而且命中的话,则会进入 DynaCache 的相关代码。如果无缓存或缓存不命中,如果是 JSP 页面,则会执行 JSP 的相关代码,否则会执行相应的逻辑。代码逻辑处理过程中,经常会访问到数据库(通过 DSL 或 EJB)或 Solr 搜索(通过 BOD 或 REST),还有可能访问到外部系统集成接口(通过 HTTP 同步调用或消息队列)。如果数据库服务器 / 搜索服务器 / 系统集成服务器分布在其他节点上,那么这些调用最终都会转化为网络访问。
以下为一个正在处理 JSP 页面中的数据库请求的执行堆栈示例,如图 3、4、5:
图 3. 堆栈实例(1)
图 4. 堆栈实例(2)
自下而上的关键代码:
查询 :Package 名 / 类名 . 方法名:com.ibm.ws.rsadapter.jdbc/WSJdbcPreparedStatement.executeQuery 或 Package 名 / 类名 . 方法名:com.ibm.ws.rsadapter.cci/WSResourceAdapterBase.executeQuery
更新:Package 名 / 类名 . 方法名:com.ibm.ws.rsadapter.jdbc/WSJdbcPreparedStatement.executeUpdate 或 Package 名 / 类名 . 方法名:com.ibm.ws.rsadapter.cci/WSResourceAdapterBase.executeUpdate
(网络读)Package 名 / 类名 . 方法名:java.net/SocketInputStream.socketRead0
(网络写)Package 名 / 类名 . 方法名:java.net/SocketOutputStream.socketWrite0
其他常见的执行堆栈举例:
这样的堆栈表示当前线程处于空闲状态(对于 Web 容器而言,即当前线程没有接收到 Web 请求)。其调用栈为:
Package 名 / 类名 . 方法名:java.lang/Object/wait
…
Package 名 / 类名 . 方法名:com.ibm.ws.util/ThreadPool$Worker. run
或者
Package 名 / 类名 . 方法名:com.ibm.io.async/AsyncLibrary. aio_getioev*
…
Package 名 / 类名 . 方法名:com.ibm.ws.util/ThreadPool$Worker. run
提交(Commit)
Package 名 / 类名 . 方法名:com.ibm.commerce.server/TransactionManager.commit
回滚(Rollback)
Package 名 / 类名 . 方法名:com.ibm.commerce.server/TransactionManager.rollback
Package 名 / 类名 . 方法名:com.ibm.ws.cache/Cache.getEntry(或 getCacheEntry)
基于 WXS 的缓存则为
Package 名 / 类名 . 方法名:com.ibm.ws.objectgrid.dynacache/RemoteCoreCacheImpl.get
-----整理自:http://www.kankanews.com/ICkengine/archives/156577.shtml
标签:
原文地址:http://www.cnblogs.com/polestar/p/4241259.html