你如何在Java中获取线程堆栈

你如何在Java中获取线程堆栈,第1张

itjobJava老师讲过:1)线程堆栈概述及基础知识

2)线程堆栈的生成原理以及相关工具

3)不同JVM线程堆栈的格式的差异(SunHotSpot、IBMJRE、OracalJRockit)

4)线程堆栈日志介绍以及解析方法

5)线程堆栈的分析和相关的技术

6)常见的问题模板(线程竟态、死锁、IO调用挂死、垃圾回收/问题、死循环等)

7)线程堆栈问题实例分析

我希望这一系列的培训能给你带来确实的帮助,所以请持续关注每周的文章更新。

但是如果我在学习过程中有疑问或者无法理解文章中的内容该怎么办?

不用担心,把我当做你的导师就好。任何关于线程堆栈的问题都可以咨询我(前提是问题不能太low)。请随意选择下面的几种方式与我取得联系:

1)直接本文下面发表评论(不好意思的话可以匿名)

2)将你的线程堆栈数据提交到RootCauseAnalysisforum

3)发Email给我,地址是@@hotmail

能帮我分析我们产品上遇到的问题么?

当然可以,如果你愿意的话可以把你的堆栈现场数据通过邮件或论坛RootCauseAnalysisforum发给我。处理实际问题是才是学习提升技能的王道。

我真心期望大家能够喜欢这个培训。所以我会尽我所能去为你提供高质量的材料,并回答大家的各种问题。

在介绍线程堆栈分析技术和问题模式之前,先要给大家讲讲基础的内容。所以在这篇帖子里,我将先覆盖到最基本的内容,这样大家就能更好的去理解JVM、中间件、以及JavaEE容器之间的交互。

JavaVM概述

Java虚拟机是JaveEE平台的基础。它是中间件和应用程序被部署和运行的地方。

JVM向中间件软件和你的Java/JavaEE程序提供了下面这些东西:

_(二进制形式的)Java/JavaEE程序运行环境

_一些程序功能特性和工具(IO基础设施,数据结构,线程管理,安全,监控等等)

_借助垃圾回收的动态内存分配与管理

你的JVM可以驻留在许多的 *** 作系统(Solaris,AIX,Windows等等)之上,并且能根据你的物理服务器配置,你可以在每台物理/虚拟服务器上安装1到多个JVM进程

JVM与中间件之间的交互

下面这张图展示了JVM、中间件和应用程序之间的高层交互模型。

如你所见,标准JavaEE应用程序的线程的分配实在中间件内核与JVM之间完成的。(当然也有例外,应用程序可以直接调用API来创建线程,这种做法并不常见,而且在使用的过程中也要特别的小心)

同时,请注意一些线程是由JVM内部来进行管理的,典型的例子就是垃圾回收线程,JVM内部使用这个线程来做并行的垃圾回收处理。

因为大多数的线程分配都是由JavaEE容器完成的,所以能够理解和认识线程堆栈跟踪,并能从线程堆栈数据中识别出它来,对你而言很重要这可以让你能够快速的知道JavaEE容器正要执行的是什么类型的请求

从一个线程转储堆栈的分析角度来看,你将能了解从JVM发现的线程池之间的不同,并识别出请求的类型

最后一节会向你提供对于HotSopVM而言什么是JVM线程堆栈的一个概述,还有你将会遇到的各种不同的线程而对IBMVM线程堆栈形式详细内容将会在第四节向你提供

请注意你可以从根本原因分析论坛获得针对本文的线程堆栈示例

JVM线程堆栈——它是什么

JVM线程堆栈是一个给定时间的快照,它能向你提供所有被创建出来的Java线程的完整清单

当服务器挂起,崩溃或者性能底下时,就需要抓取服务器的线程堆栈(Thread Dump)用于后续的分析

Thread dump提供了当前活动的线程的快照 它提供了JVM中所有Java线程的栈跟踪信息

有很多方式可用于获取Thread Dump, 一些是 *** 作系统特定的命令

*** 作系统命令获取ThreadDump:

Windows:

1 转向服务器的标准输出窗口并按下Control + Break组合键, 之后需要将线程堆栈复制到文件中

UNIX/ Linux

首先查找到服务器的进程号(process id), 然后获取堆栈

1 ps –ef  | grep java

2 kill -3 <pid>

注意一定要谨慎, 一步不慎就可能让服务器进程被杀死!


JVM 自带的工具获取线程堆栈:

JDK自带命令行工具获取PID并做ThreadDump:

1  jps

2jstack <pid>

使用JVisualVM:

Threads 标签页 →ThreadDump按钮

WebLogic 自带的获取 thread dump的工具:

1 webLogicAdmin 工具

a 打开命令提示符, 通过运行<DOMAIN_HOME>/bin/setDomainenv设置相关类路径

b 执行下面的命令

java weblogicAdmin -url t3://localhost:7001 -username weblogic -password weblogic1 THREAD_DUMP

注意: Thread Dump 会打印到标准输出, 如nohup日志或者进程窗口

2 使用 Admin Console

a 登录 Admin Console , 点击对应的服务器

b 点击Server à Monitoring àThreads

c 点击: Dump Thread Stack 按钮

3 使用WLST (WebLogic Scripting Tool)

connect(‘weblogic’,'weblogic1’,’t3://localhost:7001’)

cd(‘Servers’)

cd(‘AdminServer’)

threadDump()

disconnect()

exit()

注意: 线程堆栈将会保存在运行wlst的当前目录下

4 使用utilsThreadDumper

用法:

C:\bea\wlserver_103\server\lib>java -cp weblogicjar utilsThreadDumper

Broadcast Thread dumps disabled: must specify weblogicdebugdumpThreadAddr and

weblogicdebugdumpThreadPort

Exception in thread "main" javalangIllegalArgumentException: Port out of range

:-1

at javanetDatagramPacketsetPort(Unknown Source)

at javanetDatagramPacket<init>(Unknown Source)

at javanetDatagramPacket<init>(Unknown Source)

at utilsThreadDumpersendDumpMsg(ThreadDumperjava:124)

at utilsThreadDumpermain(ThreadDumperjava:145)

5 如果服务器是作为Windows服务的方式运行, 请运行下列命令:

WL_HOME\bin\beasvc -dump -svcname:service-name

其它一些获取Thread Dump的工具有jrcmd, jrmc(JRockit VM自带) ,Samurai, JProfiler等, 还可通过JMX编程的方式获取, 如JDK自带示例代码:

$JAVA_HOME\demo\management\FullThreadDump

多线程下载由来已久 如 FlashGet NetAnts 等工具 它们都是依懒于 >

性能优化我觉得应该分两步走,第一步:寻找性能瓶颈,第二步:性能调优;

下面分别进行分析:

第一步:寻找性能瓶颈

通常性能瓶颈的表象是资源消耗过多、外部处理系统的性能不足;或者资源消耗不多,但是程序效应还是很慢;

资源主要消耗在cpu,文件io,网络io以及内存方面,当某一资源消耗过多会造成系统响应慢;

外部处理系统的性能不足主要是所调用其他系统提供的功能或数据库的响应速度不够,外部系统慢可能也是资源消耗过多导致,数据库响应慢可以对数据库进行调优;

资源消耗不多但仍然慢主要原因是程序代码运行效率不高,未充分使用资源或程序结构不合理;

11cpu消耗分析

可以通过相关命令比如top,pidstat,找出各个类型消耗cpu的占比,最常见的就是us和sy类型分别代表用户进程消耗和线程间切换消耗;如果us过高可以找到相关的线程ID然后分析代码;如果sy过高是不是启动了过多的线程导致线程切换过多;

12文件io消耗

要跟踪线程的文件IO消耗,可以通过pidstat来查找,可以查到每秒的读写kb数;找到读写kb数多个线程,然后结合jstack找到相关的java代码,然后分析;

13网络io消耗

可以通过sar来分析网络的消耗状况,但是不能具体到每个线程所消耗的网络IO,只能对线程dump,查找产生了大量网络io的线程;

14内存消耗

结合top或pidstat,以及jvm的内存分析工具来分析内存消耗;要区分是jvm外的物理内存还是jvmheap区内存;如果是jvm外的物理内存要分析程序中DirectByteBuffer,如果是jvmheap可以通过jvisualvm来分析;

15资源消耗不多但仍然慢

主要原因是:锁竞争激烈,未充分使用硬件资源,数据量增长

第二步:性能调优

21jvm调优

主要包括各个代的大小、GC策略等;代大小的设置:避免新生代大小设置过小,或者过大;避免Survivor区过小或过大;合理设置新生代存活周期;GC策略根据吞吐量优先还是延迟优先进行设置策略;

22程序调优

1CPU消耗严重解决

us过高主要是执行线程无任何挂起动作,可以进行Threadsleep *** 作;sy过高主要是因为创建了过多的线程导致线程上下文切换;

2文件IO消耗严重解决

造成文件IO消耗严重的原因主要是多个线程写大量的数据到同一个文件,导致文件很快变的很大,从而写入速度越来越慢,并造成各线程激烈竞争争抢文件锁,常用的调优方法:异步写文件,批量读写,限流,限制文件大小;

3网络IO消耗严重解决

主要原因是同时发送或者接受的包太多,解决办法就是限流;

4内存消耗严重解决

解决:释放不必要的引用,使用对象缓存池,采用合理的缓存失效策略,合理使用softReference和WeakReference;

23资源消耗不多但仍然慢

主要原因是:锁竞争激烈,未充分使用硬件资源


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/13358923.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-07-21
下一篇 2023-07-21

发表评论

登录后才能评论

评论列表(0条)

保存