扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
通过分析Java线程堆解决Java应用程序中存在问题的技术。我们可以使用线程堆来分析诸如应用程序挂起,响应时间长以及程序崩溃等情况。在详细介绍分析线程堆的技术之前,我们先来简要地看看线程堆本身。
Java线程堆是一个运行中的Java应用程序的所有线程的一个快照。它会显示一些像当前的堆栈跟踪、状态以及线程名称之类的信息。线程列表中包括由JVM本身创建的线程(负责垃圾收集、信号处理等管理工作)和由应用程序创建的线程。
通过给JVM发送一个SIGQUIT信号,您可以得到一个线程堆。在Unix操作系统(Solaris/Linux/HP-Unix等)中,通过kill-3命令可以得到线程堆。输出出线程堆之后,应用程序继续正常运行。当您给JVM发送SIGQUIT信号时,JVM的信号处理器会通过输出线程堆来响应这一信号。当程序运行的时候,您可以在任何点得到线程堆。
线程堆的一个例子
清单1显示的就是一个使用Sun JVM 1.4.1的单线程应用程序中的线程堆的例子。main线程是主应用程序线程。所有其他的线程都是由JVM创建的,负责完成一些管理工作。当分析应用程序级的问题时,我们通常只关心应用程序线程。下面,我们来分析清单1中main线程的堆栈跟踪。
|
从这个代码片断中您可以看到,一个线程堆栈跟踪有一个名称、线程优先级(prio=5)、状态(可运行的)、源代码行号,以及方法调用。从这个堆栈跟踪中可以得到如下结论:main线程执行test类的method1方法中的一些代码。而对method1方法的调用是由同一个类的main方法完成的。您也可以看到那些方法中确切的源代码行号。
在从一些更复杂的情况去分析线程堆之前,我们先来讨论那些可以在线程堆中看到的线程的不同状态以及它们的意义。
· 可运行的:当获得CPU的使用权时就可以运行或准备好运行的状态。JRockit线程堆把这种状态称为ACTIVE。
· 在监视中等待:指在一个对象上休眠或等待上述时间,或者等待另一个线程的通知。这种情况会出现在对Thread对象调用任何sleep() 方法或者对Object调用wait() 方法时。
例如,在BEA WebLogic Server中,空闲的执行线程就处于这种状态,它们会等待一个socket阅读器线程通知它们去做一些新的工作。堆栈跟踪如下所示:
|
JVM的其他版本把这种状态称为CW。JRockit将这种状态称为WAITING。
· 等待监视实体:等待锁住一个对象(其他线程目前正控制着锁)。如果两个或者多个线程都想在同一时刻执行一个对象的某些同步代码块或方法,就会出现这种情况。请注意,锁总是加在一个对象上而不是加在独立的方法上。也就是说,如果一个线程要执行一个对象的同步方法,它必须先给那个对象加锁。
下面显示的就是这种情况下的一个线程的堆栈跟踪的例子:
|
在上述代码片断中,您们可以看到这个线程已经锁住了一个对象(6c408700),并且还在等待锁住另一个对象(6c4b9130)。
JVM的其他版本可能不会在堆栈跟踪中给出对象ID的加锁信息。这种情况下,我们可以从线程的状态中推测出线程正在等待给对象加锁。同样的状态也许会被称为MW。JRockit将这种状态称为LOCKED。
现在,我们来看看各种不同情况下的一些线程堆,并通过分析它们来寻找应用程序中的问题。
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者