「Java查看线程状态日志」java查看运行日志
本篇文章给大家谈谈Java查看线程状态日志,以及java查看运行日志对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。
本文目录一览:
- 1、怎样分析java线程堆栈日志
- 2、java获取当前线程状态。
- 3、用c语言 java 来获取当前(进程)线程状态
- 4、Java如何监视线程的状态
- 5、如何使用jstack分析线程状态
- 6、如何用java代码来监控系统内存·cpu·线程占用情况,并生成日志
怎样分析java线程堆栈日志
itjobJava老师讲过:1) 线程堆栈概述及基础知识
2) 线程堆栈的生成原理以及相关工具
3) 不同JVM线程堆栈的格式的差异(Sun HotSpot、IBM JRE、Oracal JRockit)
4) 线程堆栈日志介绍以及解析方法
5) 线程堆栈的分析和相关的技术
6) 常见的问题模板(线程竟态、死锁、IO调用挂死、垃圾回收/OutOfMemoryError问题、死循环等)
7) 线程堆栈问题实例分析
我希望这一系列的培训能给你带来确实的帮助,所以请持续关注每周的文章更新。
但是如果我在学习过程中有疑问或者无法理解文章中的内容该怎么办?
不用担心,把我当做你的导师就好。任何关于线程堆栈的问题都可以咨询我(前提是问题不能太low)。请随意选择下面的几种方式与我取得联系:
1) 直接本文下面发表评论(不好意思的话可以匿名)
2) 将你的线程堆栈数据提交到Root Cause Analysis forum
3) 发Email给我,地址是 @phcharbonneau@hotmail.com
能帮我分析我们产品上遇到的问题么?
当然可以,如果你愿意的话可以把你的堆栈现场数据通过邮件或论坛 Root Cause Analysis forum发给我。处理实际问题是才是学习提升技能的王道。
我真心期望大家能够喜欢这个培训。所以我会尽我所能去为你提供高质量的材料,并回答大家的各种问题。
在介绍线程堆栈分析技术和问题模式之前,先要给大家讲讲基础的内容。所以在这篇帖子里,我将先覆盖到最基本的内容,这样大家就能更好的去理解JVM、中间件、以及Java EE容器之间的交互。
Java VM 概述
Java虚拟机是Jave EE 平台的基础。它是中间件和应用程序被部署和运行的地方。
JVM向中间件软件和你的Java/Java EE程序提供了下面这些东西:
– (二进制形式的)Java / Java EE 程序运行环境
– 一些程序功能特性和工具 (IO 基础设施,数据结构,线程管理,安全,监控 等等.)
– 借助垃圾回收的动态内存分配与管理
你的JVM可以驻留在许多的操作系统 (Solaris, AIX, Windows 等等.)之上,并且能根据你的物理服务器配置,你可以在每台物理/虚拟服务器上安装1到多个JVM进程.
JVM与中间件之间的交互
下面这张图展示了JVM、中间件和应用程序之间的高层交互模型。
如你所见,标准Java EE应用程序的线程的分配实在中间件内核与JVM之间完成的。(当然也有例外,应用程序可以直接调用API来创建线程,这种做法并不常见,而且在使用的过程中也要特别的小心)
同时,请注意一些线程是由JVM内部来进行管理的,典型的例子就是垃圾回收线程,JVM内部使用这个线程来做并行的垃圾回收处理。
因为大多数的线程分配都是由Java EE容器完成的,所以能够理解和认识线程堆栈跟踪,并能从线程堆栈数据中识别出它来,对你而言很重要. 这可以让你能够快速的知道Java EE容器正要执行的是什么类型的请求.
从一个线程转储堆栈的分析角度来看,你将能了解从JVM发现的线程池之间的不同,并识别出请求的类型.
最后一节会向你提供对于HotSop VM而言什么是JVM线程堆栈的一个概述,还有你将会遇到的各种不同的线程. 而对 IBM VM 线程堆栈形式详细内容将会在第四节向你提供.
请注意你可以从根本原因分析论坛获得针对本文的线程堆栈示例.
JVM 线程堆栈——它是什么?
JVM线程堆栈是一个给定时间的快照,它能向你提供所有被创建出来的Java线程的完整清单.
java获取当前线程状态。
java线程的状态有下面几种状态:
/**
* Thread state for a thread which has not yet started.
*/
NEW,
/**
* Thread state for a runnable thread. A thread in the runnable
* state is executing in the Java virtual machine but it may
* be waiting for other resources from the operating system
* such as processor.
*/
RUNNABLE,
/**
* Thread state for a thread blocked waiting for a monitor lock.
* A thread in the blocked state is waiting for a monitor lock
* to enter a synchronized block/method or
* reenter a synchronized block/method after calling
* {@link Object#wait() Object.wait}.
*/
BLOCKED,
/**
* Thread state for a waiting thread.
* A thread is in the waiting state due to calling one of the
* following methods:
* ul
* li{@link Object#wait() Object.wait} with no timeout/li
* li{@link #join() Thread.join} with no timeout/li
* li{@link LockSupport#park() LockSupport.park}/li
* /ul
*
* pA thread in the waiting state is waiting for another thread to
* perform a particular action.
*
* For example, a thread that has called ttObject.wait()/tt
* on an object is waiting for another thread to call
* ttObject.notify()/tt or ttObject.notifyAll()/tt on
* that object. A thread that has called ttThread.join()/tt
* is waiting for a specified thread to terminate.
*/
WAITING,
/**
* Thread state for a waiting thread with a specified waiting time.
* A thread is in the timed waiting state due to calling one of
* the following methods with a specified positive waiting time:
* ul
* li{@link #sleep Thread.sleep}/li
* li{@link Object#wait(long) Object.wait} with timeout/li
* li{@link #join(long) Thread.join} with timeout/li
* li{@link LockSupport#parkNanos LockSupport.parkNanos}/li
* li{@link LockSupport#parkUntil LockSupport.parkUntil}/li
* /ul
*/
TIMED_WAITING,
/**
* Thread state for a terminated thread.
* The thread has completed execution.
*/
TERMINATED;
用c语言 java 来获取当前(进程)线程状态
通过调用Thread.getState()方法获取当前线程的状态。以下是我的代码,可以直接编译运行。
public class Test {
public static void main(String[] args) {
new NewThread().start(); //启动线程
}
}
class NewThread extends Thread{
public NewThread() {
super("NewThread"); //定义当前线程的名称为NewThread
}
@Override
public void run() {
System.out.println("当前线程:"+currentThread().getName()+"运行状态为:"+getState()); //打印线程的运行状态
}
}
Java如何监视线程的状态
线程池的地方在新增或者删除线程的时候加一个debug信息。
如果在命令行下面启动的话用ctrl + break就可以看到当前哪些线程在运行了。。。
如何使用jstack分析线程状态
jstack 线程状态
jstack 线程里,值得关注的线程状态有:
死锁,Deadlock(重点关注)
执行中,Runnable
等待资源,Waiting
on condition(重点关注)
等待获取监视器,Waiting
on monitor entry(重点关注)
暂停,Suspended
对象等待中,Object.wait()
或 TIMED_WAITING
阻塞,Blocked(重点关注)
停止,Parked
下面我们先从第一个例子开始分析,然后再列出不同线程状态的含义以及注意事项,最后再补充两个实例。
综合示范一:Waiting
to lock 和 Blocked
实例如下:
"RMI TCP Connection(267865)-172.16.5.25" daemon prio=10 tid=0x00007fd508371000 nid=0x55ae waiting
for monitor entry [0x00007fd4f8684000]
java.lang.Thread.State: BLOCKED
(on object monitor)
at org.apache.log4j.Category.callAppenders(Category.java:201)
- waiting
to lock 0x00000000acf4d0c0 (a org.apache.log4j.Logger)
at org.apache.log4j.Category.forcedLog(Category.java:388)
at org.apache.log4j.Category.log(Category.java:853)
at org.apache.commons.logging.impl.Log4JLogger.warn(Log4JLogger.java:234)
at com.tuan.core.common.lang.cache.remote.SpyMemcachedClient.get(SpyMemcachedClient.java:110)
……
1)线程状态是 Blocked,阻塞状态。说明线程等待资源超时!
2)“ waiting to lock 0x00000000acf4d0c0”指,线程在等待给这个 0x00000000acf4d0c0 地址上锁(英文可描述为:trying
to obtain 0x00000000acf4d0c0 lock)。
3)在 dump 日志里查找字符串 0x00000000acf4d0c0,发现有大量线程都在等待给这个地址上锁。如果能在日志里找到谁获得了这个锁(如locked 0x00000000acf4d0c0 ),就可以顺藤摸瓜了。
4)“waiting for monitor entry”说明此线程通过 synchronized(obj) {……} 申请进入了临界区,从而进入了下图1中的“Entry
Set”队列,但该 obj 对应的 monitor 被其他线程拥有,所以本线程在 Entry Set 队列中等待。
5)第一行里,"RMI TCP Connection(267865)-172.16.5.25"是 Thread Name 。tid指Java Thread id。nid指native线程的id。prio是线程优先级。[0x00007fd4f8684000]是线程栈起始地址。
Dump文件中的线程状态含义及注意事项
含义如下所示:
Deadlock:死锁线程,一般指多个线程调用间,进入相互资源占用,导致一直等待无法释放的情况。
Runnable:一般指该线程正在执行状态中,该线程占用了资源,正在处理某个请求,有可能正在传递SQL到数据库执行,有可能在对某个文件操作,有可能进行数据类型等转换。
Waiting on condition:等待资源,或等待某个条件的发生。具体原因需结合
stacktrace来分析。
一种情况是网络非常忙,几乎消耗了所有的带宽,仍然有大量数据等待网络读写;
另一种情况也可能是网络空闲,但由于路由等问题,导致包无法正常的到达。
如果堆栈信息明确是应用代码,则证明该线程正在等待资源。一般是大量读取某资源,且该资源采用了资源锁的情况下,线程进入等待状态,等待资源的读取。
又或者,正在等待其他线程的执行等。
如果发现有大量的线程都在处在 Wait on condition,从线程 stack看,正等待网络读写,这可能是一个网络瓶颈的征兆。因为网络阻塞导致线程无法执行。
另外一种出现 Wait on condition的常见情况是该线程在 sleep,等待 sleep的时间到了时候,将被唤醒。
Blocked:线程阻塞,是指当前线程执行过程中,所需要的资源长时间等待却一直未能获取到,被容器的线程管理器标识为阻塞状态,可以理解为等待资源超时的线程。
Waiting for monitor entry 和 in Object.wait():Monitor是
Java中用以实现线程之间的互斥与协作的主要手段,它可以看成是对象或者 Class的锁。每一个对象都有,也仅有一个
monitor。从下图1中可以看出,每个 Monitor在某个时刻,只能被一个线程拥有,该线程就是 “Active
Thread”,而其它线程都是 “Waiting Thread”,分别在两个队列 “ Entry Set”和 “Wait Set”里面等候。在
“Entry Set”中等待的线程状态是 “Waiting for monitor entry”,而在 “Wait Set”中等待的线程状态是
“in Object.wait()”。
图1 A Java Monitor
综合示范二:Waiting
on condition 和 TIMED_WAITING
实例如下:
"RMI TCP Connection(idle)" daemon prio=10 tid=0x00007fd50834e800 nid=0x56b2 waiting
on condition [0x00007fd4f1a59000]
java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for 0x00000000acd84de8 (a
java.util.concurrent.SynchronousQueue$TransferStack)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:198)
at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:424)
at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:323)
at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:874)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:945)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
at java.lang.Thread.run(Thread.java:662)
1)“TIMED_WAITING (parking)”中的 timed_waiting 指等待状态,但这里指定了时间,到达指定的时间后自动退出等待状态;parking指线程处于挂起中。
2)“waiting on condition”需要与堆栈中的“parking to wait for 0x00000000acd84de8 (a
java.util.concurrent.SynchronousQueue$TransferStack)”结合来看。首先,本线程肯定是在等待某个条件的发生,来把自己唤醒。其次,SynchronousQueue
并不是一个队列,只是线程之间移交信息的机制,当我们把一个元素放入到 SynchronousQueue
中时必须有另一个线程正在等待接受移交的任务,因此这就是本线程在等待的条件。
3)别的就看不出来了。
综合示范三:in
Obejct.wait() 和 TIMED_WAITING
实例如下:
"RMI RenewClean-[172.16.5.19:28475]"
daemon prio=10 tid=0x0000000041428800 nid=0xb09 in Object.wait() [0x00007f34f4bd0000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on 0x00000000aa672478 (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
- locked 0x00000000aa672478 (a java.lang.ref.ReferenceQueue$Lock)
at sun.rmi.transport.DGCClient$EndpointEntry$RenewCleanThread.run(DGCClient.java:516)
at java.lang.Thread.run(Thread.java:662)
1)“TIMED_WAITING (on object monitor)”,对于本例而言,是因为本线程调用了 java.lang.Object.wait(long timeout) 而进入等待状态。
2)“Wait Set”中等待的线程状态就是“ in Object.wait() ”。当线程获得了
Monitor,进入了临界区之后,如果发现线程继续运行的条件没有满足,它则调用对象(一般就是被 synchronized 的对象)的
wait() 方法,放弃了 Monitor,进入 “Wait Set”队列。只有当别的线程在该对象上调用了
notify() 或者 notifyAll() ,“ Wait Set”队列中线程才得到机会去竞争,但是只有一个线程获得对象的
Monitor,恢复到运行态。
3)RMI RenewClean 是 DGCClient 的一部分。DGC 指的是 Distributed GC,即分布式垃圾回收。
4)请注意,是先 locked 0x00000000aa672478,后 waiting on 0x00000000aa672478,之所以先锁再等同一个对象,请看下面它的代码实现:
static private class Lock { };
private Lock lock = new Lock();
public Reference? extends T remove(long
timeout)
{
synchronized (lock) {
Reference? extends T r = reallyPoll();
if (r != null) return r;
for (;;) {
lock.wait(timeout);
r = reallyPoll();
……
}
}
即,线程的执行中,先用 synchronized 获得了这个对象的 Monitor(对应于 locked 0x00000000aa672478 );当执行到 lock.wait(timeout);,线程就放弃了 Monitor 的所有权,进入“Wait Set”队列(对应于 waiting
on 0x00000000aa672478 )。
5)从堆栈信息看,是正在清理 remote references to remote objects ,引用的租约到了,分布式垃圾回收在逐一清理呢。
如何用java代码来监控系统内存·cpu·线程占用情况,并生成日志
可以学习软件包 java.lang.management
提供管理接口,用于监视和管理 Java 虚拟机以及 Java 虚拟机在其上运行的操作系统。
ClassLoadingMXBean
用于 Java 虚拟机的类加载系统的管理接口。
CompilationMXBean
用于 Java 虚拟机的编译系统的管理接口。
GarbageCollectorMXBean
用于 Java 虚拟机的垃圾回收的管理接口。
MemoryManagerMXBean
内存管理器的管理接口。
MemoryMXBean
Java 虚拟机内存系统的管理接口。
MemoryPoolMXBean
内存池的管理接口。
OperatingSystemMXBean
用于操作系统的管理接口,Java 虚拟机在此操作系统上运行。
RuntimeMXBean
Java 虚拟机的运行时系统的管理接口。
ThreadMXBean
Java 虚拟机线程系统的管理接口。
更多请访问(bug315)
Java查看线程状态日志的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于java查看运行日志、Java查看线程状态日志的信息别忘了在本站进行查找喔。