一、官方解读:
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
*************************************
【温馨提示】
如果您觉得满意,可以选择支持下,您的支持是我最大的动力:
分享到:
相关推荐
JVM 的内存结构可以分为 6 个区域:PC 寄存器、JVM 栈、堆(Heap)、方法区、运行时常量池和直接内存。每个区域都有其特定的功能和作用,以下是对每个区域的详细介绍: PC 寄存器(PC Register) PC 寄存器是一块...
通过这种方式,JVM 能够高效地管理和执行 Java 程序中的方法调用。 ##### 2.4 JVM 的内存分配 内存分配是 JVM 运行过程中至关重要的环节。对于 Java 程序来说,大部分的对象都存储在堆(Heap)中。堆是 JVM 管理的...
1. **程序计数器(PC寄存器)**:这是一个较小的内存区域,用于存储当前线程正在执行的字节码指令的地址。在多线程环境下,每个线程都有自己的程序计数器,当线程执行本地方法时,其值为Undefined。程序计数器是线程...
4. ProgramCounter(程序计数器):每一个线程都有它自己的PC寄存器,也是该线程启动时创建的。PC寄存器的内容总是指向下一条将被执行指令的地址,这里的地址可以是一个本地指针,也可以是在方法区中相对应于该方法...
方法区域(在HotSpot JVM中称为Metaspace)用于存储类的元数据,包括类的信息、静态变量、常量、Field信息和方法信息等。这部分区域是全局共享的,当需要的内存超出其容量限制时,会抛出`OutOfMemoryError`。 #####...
Java虚拟机(JVM)是Java程序运行的核心,它的基本结构和内存管理对于理解Java程序的性能至关重要。本文将深入探讨JVM的五个主要区域,以及可能出现的内存溢出问题。 首先,JVM的主要区域包括: 1. **方法区...
《JVM性能调优——JVM内存整理及GC回收》是针对Java开发人员的重要主题,尤其是在大型企业级应用中,确保JVM(Java虚拟机)的高效运行是至关重要的。本资料深入探讨了如何通过调整JVM内存设置和优化垃圾回收机制来...
JVM的内存模型分为五个部分:方法区、堆(heap)、栈(stack)、PC寄存器和本地方法栈。方法区用于存储类的元数据,堆用于存储对象实例,栈用于存储线程的执行上下文,PC寄存器用于存储当前执行的指令地址,本地方法栈...
2. **内存模型**:JVM内存分为堆内存(Heap)、栈内存(Stack)、方法区(Method Area)、程序计数器(PC Register)和本地方法栈(Native Method Stack)。堆内存用于存储对象实例,栈内存存储方法调用,方法区存储...
3. **方法区(Method Area)**:也称为永久代,在Hotspot JVM中,这部分存储类加载器ClassLoader加载的类信息,包括元数据、常量池、字段、静态变量和编译后的字节码等。在Java 8及以后版本,这部分被替换为元空间...
JVM内存区域划分是Java虚拟机(JVM)中的一种内存管理机制,主要分为五个部分:程序计数器、Java栈、本地方法栈、堆和方法区。这些区域各自扮演着不同的角色,共同组成了JVM的内存管理系统。 程序计数器 程序...
5. PC寄存器(Program Counter Register):记录当前线程执行的指令地址。 三、垃圾收集与内存优化 1. 垃圾收集器:包括串行、并行、并发、分代等不同策略,如 SERIAL、PARALLEL、CMS、G1等,选择合适的垃圾收集器...
在实际开发中,我们可能还会遇到JVM相关的性能监控和诊断工具,如JConsole、VisualVM等,它们可以帮助我们观察和分析JVM的运行状态,包括内存使用、CPU消耗、线程状况等。 此外,JVM的调优是一个持续优化的过程,...
1. **程序计数器寄存器**(Program Counter Register, pc):记录当前线程所执行的字节码指令地址。 2. **操作数栈顶寄存器**(Operand Stack Top Register, optop):指示操作数栈顶的位置。 3. **帧指针寄存器**...
JVM的体系结构包括几个重要组成部分:类装载器(ClassLoader)、执行引擎(ExecutionEngine)、本地方法栈(Native Method Stack)、PC(程序计数器)寄存器等。其中,类装载器负责将.class文件加载进内存,执行引擎...
- **内存的功能划分**:主要包括方法区(Method Area)、永久代(PermGen space)、虚拟机栈(VM stack)、本地方法栈(Native Method Stack)、程序计数器(PC Register)等。 在程序执行的过程中,JVM会根据需要...
Java虚拟机(JVM)的核心组件之一便是其运行时数据区域,这一区域负责存储程序运行过程中产生的各种数据。为了更好地理解这部分内容,我们将深入探讨运行时数据区域内的各个组成部分。 ##### 1.1 PC 寄存器 (Program ...
Java性能调优,特别是关于垃圾回收机制的分析和指导,是优化Java应用程序的关键环节。Java的垃圾回收(Garbage Collection, GC)是自动管理内存的一种机制,它负责识别并清理那些不再使用的对象,以释放内存资源。...
4. **PC寄存器(Program Counter Register)**:每个线程也有一个PC寄存器,用于记录当前线程正在执行的字节码指令地址。 5. **本地方法栈(Native Method Stack)**:为执行Java Native Interface(JNI)调用的...