通过 Javacore 了解线程运行状况
Javacore 是一个当前 JVM 运行状态的快照。通过对Javacore 的分析,可以了解在 JVM 中运行的应用程序的当前状态,比如是否“卡”在某一点上,或在某些代码上运行时间太长。
Javacore 的基本内容
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 产生的原因,时间以及文件的路径。最常见的有下面三种:
- user:SIGQUIT 信号
- gpf:程序一般保护性错误导致系统崩溃
- systhrow:JVM 内部抛出的异常
GPINFO 信息块:GPF(一般保护性错误)信息
ENVINFO 信息块:系统运行时的环境和 JVM 参数
MEMINFO 信息块:内存使用情况和垃圾回收情况
LOCKS 信息块:用户监视器(monitor)和系统监视器(monitor)情况
THREADS 信息块:所有 java 线程的状态信息和执行堆栈
CLASSES 信息块:类加载信息
Javacore 中的线程可分为以下几种状态:
- 死锁(Deadlock)【重点关注】:一般指多个线程调用间,进入相互资源占用,导致一直等待无法释放的情况。
- 执行中(Runnable)【重点关注】:一般指该线程正在执行状态中,该线程占用了资源,正在处理某个请求,有可能在对某个文件操作,有可能进行数据类型等转换等。
- 等待资源(Waiting on condition)【重点关注】:等待资源,如果堆栈信息明确是应用代码,则证明该线程正在等待资源,一般是大量读取某资源、且该资源采用了资源锁的情况下,线程进入等待状态。又或者,正在等待其他线程的执行等。
- 等待监控器检查资源(Waiting on monitor)
- 暂停(Suspended)
- 对象等待中(Object.wait())
- 阻塞(Blocked)【重点关注】:指当前线程执行过程中,所需要的资源长时间等待却一直未能获取到,被容器的线程管理器标识为阻塞状态,可以理解为等待资源超时的线程。这种情况在应用的日志中,一般可以看到 CPU 饥渴,或者某线程已执行了较长时间的信息。
- 停止(Parked)
通过对 Javacore 数据的分析经验,结合对具体应用代码逻辑的理解,有经验的工程师可以直接通过文本编辑器查看原始 Javacore 文件来分析当前应用程序的运行状态。一般初学者则需要通过一些工具进行更直观的分析。图形化分析工具 TMDA
WC 线程执行堆栈分析
不论是否利用 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)

自下而上的关键代码:
- Web 容器处理请求:Package 名 / 类名 . 方法名:com.ibm.ws.webcontainer/WebContainer.handleRequest
- RuntimeFilter:Package 名 / 类名 . 方法名:com.ibm.commerce.webcontroller/RuntimeServletFilter.doFilterAction
- Servlet 处理:Package 名 / 类名 . 方法名:com.ibm.commerce.struts/ECActionServlet.doGet 或者 Package 名 / 类名 . 方法名:com.ibm.commerce.struts/ECActionServlet.doPost
- JSP 处理:Package 名 / 类名 . 方法名:com.ibm._jsp/_(JSP 文件名 )._jspService
- Command 执行(图例为 BOD command):Package 名 / 类名 . 方法名:com.ibm.commerce.*/Abstract(*)CmdImpl.performExecute
- DSL:Package 名 / 类名 . 方法名:com.ibm.commerce.foundation.server.services.dataaccess/AbstractDataServiceFacade.*
- JDBC:
查询 :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
- 数据库驱动代码:DB2 Package 名:com.ibm.db2.* 或 Oracle Package 名 / 类名 . 方法名:oracle.jdbc.driver/OraclePreparedStatement.executeInternal
- 外部网络访问:
(网络读)Package 名 / 类名 . 方法名:java.net/SocketInputStream.socketRead0 (网络写)Package 名 / 类名 . 方法名:java.net/SocketOutputStream.socketWrite0
其他常见的执行堆栈举例:
- 空闲(Idle)
这样的堆栈表示当前线程处于空闲状态(对于 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
- 事务(Transaction)处理
提交(Commit) Package 名 / 类名 . 方法名:com.ibm.commerce.server/TransactionManager.commit 回滚(Rollback) Package 名 / 类名 . 方法名:com.ibm.commerce.server/TransactionManager.rollback
- 缓存(DynaCache)读取
Package 名 / 类名 . 方法名:com.ibm.ws.cache/Cache.getEntry(或 getCacheEntry) 基于 WXS 的缓存则为 Package 名 / 类名 . 方法名:com.ibm.ws.objectgrid.dynacache/RemoteCoreCacheImpl.get
- MultiClick 处理:Package 名 / 类名 . 方法名:com.ibm.commerce.webcontroller.doubleclick/MultiClickRequestHandler. waitForResponse
- 消息处理(MQ):Package 名 / 类名 . 方法名:com.ibm.mq.jmqi.remote.internal/RemoteRcvThread.run
- 搜索(Solr)处理:Package 名 / 类名 . 方法名:org.apache.solr.client.solrj/SolrServer.query
- REST 处理:Package 名 / 类名 . 方法名:com.ibm.commerce.foundation.internal.client.util/RESTHandler.execute
-----整理自:http://www.kankanews.com/ICkengine/archives/156577.shtml
通过 Javacore 了解线程运行状况的更多相关文章
- 通过 Javacore 诊断线程挂起等性能问题
http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1406_tuzy_javacore/1406_tuzy_jav ...
- (转)通过 Javacore 诊断线程挂起等性能问题
原文:https://www.ibm.com/developerworks/cn/websphere/library/techarticles/1406_tuzy_javacore/1406_tuzy ...
- 你真的了解 MySQL 数据库的运行状况吗?
2015年第三方市场调查机构 Evans 数据公司最近公布的一系列客户调查数据显示,在过去两年里,MySQL 在所有开发者使用的数据库中获得了25%的市场份额,Evans 公司的本次调查显示,数据库的 ...
- 和系统运行状况相关的Shell命令总结
1. Linux的实时监测命令(watch): watch 是一个非常实用的命令,可以帮你实时监测一个命令的运行结果,省得一遍又一遍的手动运行.该命令最为常用的两个选项是-d和-n,其中-n表 ...
- Linux Shell常用技巧(八) 系统运行状况
十八. 和系统运行状况相关的Shell命令: 1. Linux的实时监测命令(watch): watch 是一个非常实用的命令,可以帮你实时监测一个命令的运行结果,省得一遍又一遍的手动 ...
- 多个线程运行MR程序时hadoop出现的问题
夜间多个任务同时并行,总有几个随机性有任务失败,查看日志: cat -n ads_channel.log |grep "Caused by" Caused by: java.uti ...
- 监控 SQL Server (2005/2008) 的运行状况
Microsoft SQL Server 2005 提供了一些工具来监控数据库.方法之一是动态管理视图.动态管理视图 (DMV) 和动态管理函数 (DMF) 返回的服务器状态信息可用于监控服务器实例的 ...
- apachetop 实时监测web服务器运行状况
apachetop 实时监测web服务器运行状况 我们经常会需要知道服务器的实时监测服务器的运行状况,比如哪些 URL 的访问量最大,服务器每秒的请求数,哪个搜索引擎正在抓取我们网站?面对这些问题 ...
- healthMonitoring与运行状况监视
配置针对应用程序的运行状况监视的一个服务 配置节内容比以往的较为复杂,如下 <healthMonitoring Enabled="true|false" heartbeatI ...
随机推荐
- [经典算法] 排列组合-N元素集合的所有子集(一)
题目说明: 给定一组数字或符号,产生所有可能的集合(包括空集合),例如给定1 2 3,则可能的集合为:{}.{1}.{1,2}.{1,2,3}.{1,3}.{2}.{2,3}.{3}. 题目解析: 如 ...
- node.js学习的资源整理
node中文社区 Node.js专业中文社区:https://cnodejs.org/ node文档 node.js 中文api :http://nodeapi.ucdok.com/ node.js入 ...
- Umbraco(2) - Creating Your First Template and Content Node(翻译文档)
创建(编辑)你的第一个模板(Template) 展开 Settings > Templates文件夹 - 然后你应该看到子节点名为"Homepage" - 这是我们在创建Do ...
- codeforces 675A A. Infinite Sequence(水题)
题目链接: A. Infinite Sequence time limit per test 1 second memory limit per test 256 megabytes input st ...
- Python15-day1课后作业
功能:编写一个用户登录接口 要求:1)根据提示输入用户名.密码信息 2)输入的用户.密码正确则显示欢迎信息 3)连续三次输入错误则锁定账号 #coding=utf-8import sys,os,get ...
- javascript面向对象的理解(一)
第一次在园子发文: 关于js面向对象的理解: 工厂方式是什么?构造函数是什么?原形链?对象的引用? 1.对象是什么? 在js接触的比较多的就是对象了,比如: var arr = []; arr.num ...
- Table of Contents - TCP/IP
网络访问层 Ethernet II 网际层 IP IPv4 报文格式 ICMP ICMP 报文分析 ping: 向网络主机发送 ICMP ECHO_REQUEST 包 ARP ARP 过程 arp 命 ...
- MVC3 Razor视图引擎的基础语法
好久没有关注微软的开发了,今天看到了MVC3,顺便学习学习,我觉得Razor是个不错的做法,比使用<%%>简单多了,而且好看.首先“_”开头的cshtml文档将不能在服务器上访问,和asp ...
- win8升级win10后的windows.old怎么删除
现在win10只是出了预览版本,还没有出正式版,但是相信一部分朋友都与小D一样,喜欢尝鲜,已上用上了win10了. 有些人是通过win8或是8.1直接安装升级上去的,这样操作是安装方便,但是系统会为了 ...
- [老老实实学WCF] 第三篇 在IIS中寄存服务
老老实实学WCF 第三篇 在IIS中寄宿服务 通过前两篇的学习,我们了解了如何搭建一个最简单的WCF通信模型,包括定义和实现服务协定.配置服务.寄宿服务.通过添加服务引用的方式配置客户端并访问服务.我 ...