`
can_do
  • 浏览: 249902 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

JVM中stack和程序寄存器pc信息获取和分析

阅读更多
一、官方解读:

jstack prints Java stack traces of Java threads for a given Java process or core file or a remote debug server.
For each Java frame, the full class name, method name, 'bci' (byte code index) and line number, if available, are printed.
With the -m option, jstack prints both Java and native frames of all threads along with the 'pc' (program counter).
采用jstack默认命令,仅输出Java frame(Java帧),对于每一个java frame,如果可用,完整类名、方法名、字节码索引(bci)和行号都会被输出;
采用附带-m参数,jstack会将所有线程的java frame和native frame信息都打印出来,并且附带PC信息输出;

二、获取命令:

jstack <pid> =>

"ContainerBackgroundProcessor[StandardEngine[Tomcat]]" #18 daemon prio=5 os_prio=0 tid=0x00007fb028f26000 nid=0xc58 waiting on condition [0x00007fafc0376000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
	at java.lang.Thread.sleep(Native Method)
	at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1357)
	at java.lang.Thread.run(Thread.java:745)


jstack -m <pid> =>

>>>Interpreted Frame
----------------- 3160 -----------------
0x00007fb02e6ced12	__pthread_cond_timedwait + 0x132
0x00007fb02d819d63	_ZN2os5sleepEP6Threadlb + 0x283
0x00007fb02d61b8d2	JVM_Sleep + 0x3b2
0x00007fb019b67c31	<Unknown compiled code>
0x00007fb01900798d	* org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run() bci:46 line:1357 (Interpreted frame)
0x00007fb0190079d2	* java.lang.Thread.run() bci:11 line:745 (Interpreted frame)
0x00007fb0190004e7	<StubRoutines>
0x00007fb02d588616	_ZN9JavaCalls11call_helperEP9JavaValueP12methodHandleP17JavaCallArgumentsP6Thread + 0x1056
0x00007fb02d588b21	_ZN9JavaCalls12call_virtualEP9JavaValue11KlassHandleP6SymbolS4_P17JavaCallArgumentsP6Thread + 0x321
0x00007fb02d588fc7	_ZN9JavaCalls12call_virtualEP9JavaValue6Handle11KlassHandleP6SymbolS5_P6Thread + 0x47
0x00007fb02d61fd80	_ZL12thread_entryP10JavaThreadP6Thread + 0xa0
0x00007fb02d965dcf	_ZN10JavaThread17thread_main_innerEv + 0xdf
0x00007fb02d965efc	_ZN10JavaThread3runEv + 0x11c
0x00007fb02d8199d8	_ZL10java_startP6Thread + 0x108


>>>Compiled Frame

----------------- 3263 -----------------
0x00007fb02e6ced12	__pthread_cond_timedwait + 0x132
0x00007fb02d80464f	_ZN13ObjectMonitor4waitElbP6Thread + 0x27f
0x00007fb02d623e65	JVM_MonitorWait + 0x1a5
0x00007fb01a3b2a68	<Unknown compiled code>
0x00007fb01addd9bc	* java.util.TimerThread.mainLoop() bci:201 line:552 (Compiled frame)
* java.util.TimerThread.run() bci:1 line:505 (Interpreted frame)
0x00007fb0190004e7	<StubRoutines>
0x00007fb02d588616	_ZN9JavaCalls11call_helperEP9JavaValueP12methodHandleP17JavaCallArgumentsP6Thread + 0x1056
0x00007fb02d588b21	_ZN9JavaCalls12call_virtualEP9JavaValue11KlassHandleP6SymbolS4_P17JavaCallArgumentsP6Thread + 0x321
0x00007fb02d588fc7	_ZN9JavaCalls12call_virtualEP9JavaValue6Handle11KlassHandleP6SymbolS5_P6Thread + 0x47
0x00007fb02d61fd80	_ZL12thread_entryP10JavaThreadP6Thread + 0xa0
0x00007fb02d965dcf	_ZN10JavaThread17thread_main_innerEv + 0xdf
0x00007fb02d965efc	_ZN10JavaThread3runEv + 0x11c
0x00007fb02d8199d8	_ZL10java_startP6Thread + 0x108

3160 ---> nid=0xc58

三、比对分析:

1> jstack -m命令采用mixed模式,会将java frame和native frame都打印出来,
比对jstack不带-m和带-m的参数,可以看到:
>>>>所记录线程号:16进制表示的nid号同10进制的数字是一致的;
>>>>java method方法在程序寄存器PC中体现出的是BCI,即ByteCodeIndex,字节码索引或者字节码执行的行号
>>>>native methohd通过16进制的数字偏移量来表示
>>>>程序寄存器PC中不存放native method的地址信息吗?=>【是】
>>>>jstack -m命令会输出程序寄存器PC中的信息;(那程序寄存器PC存的是什么就知道了)
>>>>从Interpreted frame和Compiled frame标识出是对应到Java method的,本质是bci标识;
>>>>注意标【*】为PC中存储的java frame bci和line


四、小结
定义:程序计数器是一块较小的内存空间,可以看作是当前线程所执行的字节码行号指示器,也可称之为PC寄存器;
字节码解释器工作时通过改变程序计数器的值来选取下一条需要执行的字节码指令,
分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。
=>执行native本地方法时,程序计数器的值为空(Undefined)
【特性】
>>>在任何确定的时刻,一个处理器(对于多核处理器是一个内核)都只会执行一条线程中的指令;
>>>每条线程都有一个独立的线程计数器(各条线程之间的计数器互不影响,独立存储);
>>>Java方法:则这个计数器记录的是正在执行的虚拟机字节码指令的地址
>>>Native方法:计数器值为空(Undefined),是这样吗?=>【是】PC属于JVM内存范畴,不记录本地方法执行位置;
  ===>执行java方法,计数器记录虚拟机字节码指令的地址(BCI);
  ===>执行native方法,计数器为空(undefined);
>>>此内存区域是唯一在Java虚拟机规范中没有规定任何OutOfMemoryError的区域;
>>>PC寄存器是对物理PC寄存器的一种抽象模拟,线程私有,生命周期与线程的生命周期保持一致

【注意】程序寄存器PC分Java PC和 machine PC的,一般我们讲的是Java PC(因为这个属于JVM 内存模型范围中的),但是在jstack -m时,会将machine PC的本地方法执行的记录号也输出来的;

简言之:Java PC存储的是BCI(相对值)和要执行的字节码的行号(绝对值),当BCI=0时,无line号;

【Tip:样例stack frame】
【GroupA】
"http-nio-9605-exec-28" #10027 daemon prio=5 os_prio=0 tid=0x00007faf50001800 nid=0x1476 waiting on condition [0x00007fafb25b7000]
   java.lang.Thread.State: WAITING (parking)
	at sun.misc.Unsafe.park(Native Method)
	- parking to wait for  <0x00000000e1b31770> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
	at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
	at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
	at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
	at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
	at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)

----------------- 5238 -----------------
0x00007fb02e6ce965	__pthread_cond_wait + 0xc5
0x00007fb02d98c1e5	Unsafe_Park + 0xf5
0x00007fb0196891aa	<Unknown compiled code>
***************************************************
【GroupB】
"NioBlockingSelector.BlockPoller-1" #30 daemon prio=5 os_prio=0 tid=0x00007fb02b0c1000 nid=0xc71 runnable [0x00007fafb26b8000]
   java.lang.Thread.State: RUNNABLE
	at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
	at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269)
	at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:93)
	at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
	- locked <0x00000000e1b334c8> (a sun.nio.ch.Util$2)
	- locked <0x00000000e1b334b8> (a java.util.Collections$UnmodifiableSet)
	- locked <0x00000000e1b33390> (a sun.nio.ch.EPollSelectorImpl)
	at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
	at org.apache.tomcat.util.net.NioBlockingSelector$BlockPoller.run(NioBlockingSelector.java:298)

----------------- 3185 -----------------
0x00007fb02dfda483	__GI_epoll_wait + 0x33
0x00007fb01921af32	<Unknown compiled code>
**************************************
【GroupC】
"spring.cloud.inetutils" #23 daemon prio=5 os_prio=0 tid=0x00007fb02a423000 nid=0xc63 waiting on condition [0x00007fafb3a06000]
   java.lang.Thread.State: WAITING (parking)
	at sun.misc.Unsafe.park(Native Method)
	- parking to wait for  <0x00000000e15324d8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
	at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
	at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
	at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)


----------------- 3171 -----------------
0x00007fb02e6ce965	__pthread_cond_wait + 0xc5
0x00007fb02d98c1e5	Unsafe_Park + 0xf5
0x00007fb0190156d4	* sun.misc.Unsafe.park(boolean, long) bci:0 (Interpreted frame)
0x00007fb01900798d	* java.util.concurrent.locks.LockSupport.park(java.lang.Object) bci:14 line:175 (Interpreted frame)
0x00007fb01900798d	* java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await() bci:42 line:2039 (Interpreted frame)
0x00007fb0190079d2	* java.util.concurrent.LinkedBlockingQueue.take() bci:29 line:442 (Interpreted frame)
0x00007fb0190077e4	* java.util.concurrent.ThreadPoolExecutor.getTask() bci:149 line:1067 (Interpreted frame)
0x00007fb019007710	* java.util.concurrent.ThreadPoolExecutor.runWorker(java.util.concurrent.ThreadPoolExecutor$Worker) bci:26 line:1127 (Interpreted frame)
0x00007fb01900798d	* java.util.concurrent.ThreadPoolExecutor$Worker.run() bci:5 line:617 (Interpreted frame)
0x00007fb0190079d2	* java.lang.Thread.run() bci:11 line:745 (Interpreted frame)
0x00007fb0190004e7	<StubRoutines>
0x00007fb02d588616	_ZN9JavaCalls11call_helperEP9JavaValueP12methodHandleP17JavaCallArgumentsP6Thread + 0x1056
0x00007fb02d588b21	_ZN9JavaCalls12call_virtualEP9JavaValue11KlassHandleP6SymbolS4_P17JavaCallArgumentsP6Thread + 0x321
0x00007fb02d588fc7	_ZN9JavaCalls12call_virtualEP9JavaValue6Handle11KlassHandleP6SymbolS5_P6Thread + 0x47
0x00007fb02d61fd80	_ZL12thread_entryP10JavaThreadP6Thread + 0xa0
0x00007fb02d965dcf	_ZN10JavaThread17thread_main_innerEv + 0xdf
0x00007fb02d965efc	_ZN10JavaThread3runEv + 0x11c
0x00007fb02d8199d8	_ZL10java_startP6Thread + 0x108
*************************************


【温馨提示】
如果您觉得满意,可以选择支持下,您的支持是我最大的动力:

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics