输出java进程的jstack信息示例分享 通过线程堆栈信息分析java线程

下面是详细讲解“输出java进程的jstack信息示例分享 通过线程堆栈信息分析java线程”的完整攻略。

什么是jstack信息

jstack 是 JDK 自带的一款堆栈跟踪工具,用于查看 Java 进程中各个线程的运行状态以及占用资源情况。通过分析线程堆栈信息,可以快速定位代码中的性能问题,排查进程死锁等问题。

如何输出jstack信息

下面是输出 java 进程的 jstack 信息的步骤:

  1. 打开命令行窗口,输入 jps 命令找到目标 java 进程的 PID。
  2. 输入 jstack -l PID 命令输出目标 java 进程的 jstack 信息到控制台或文件中。

例如,jps 命令输出:

22444 java

jstack 命令输出:

jstack -l 22444 >> jstack_out.log

其中 -l 参数表示输出详细堆栈信息,>> 表示将输出追加到文件 jstack_out.log 中。

如何分析jstack信息

输出的 jstack 信息通常是一份数千行的代码调用堆栈信息,如何快速定位其中的问题所在呢?下面是几个常见的线程问题示例及解析。

示例一:死锁问题

假设输出的 jstack 信息中存在两个线程 A 和 B,它们分别持有对象锁和等待对方的对象锁,形成了死锁。

"Thread-1" #11 prio=5 os_prio=0 tid=0x00007efe152fc800 nid=0x2403 waiting on condition [0x0000700008a23000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000006d5d72c68> (a java.lang.Object)
        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:1074)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)

"Thread-2" #12 prio=5 os_prio=0 tid=0x00007efe153b9800 nid=0x3803 waiting on condition [0x0000700008b26000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000006d5d72c20> (a java.lang.Object)
        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:1074)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)

通过上面的代码堆栈信息,可以看到线程 A 和 B 分别处于 WAITING 状态,且都在等待同一个对象锁 <0x00000006d5d72c68><0x00000006d5d72c20>,导致两个线程相互等待进入死锁状态。

示例二:内存泄漏问题

假设输出的 jstack 信息中存在一个线程 A,在执行完业务逻辑后,堆栈信息中有大量关于 com.example.MyClass 的引用信息。

"Thread-1" #11 prio=5 os_prio=0 tid=0x00007efe152fc800 nid=0x2403 waiting on condition [0x0000700008a23000]
   java.lang.Thread.State: RUNNABLE
        at com.example.MyClass.handleRequest(MyClass.java:39)
        <more code>

        r37c92c4@80c668d6 pool-15-thread-1] [INFO ] 2017-11-05 09:54:54 The phantom references follow:
        r37c92c4@80c668d6 pool-15-thread-1] [INFO ] 2017-11-05 09:54:54 <java.lang.ref.PhantomReference@30f39991> (com.example.MyClass)
        r37c92c4@80c668d6 pool-15-thread-1] [INFO ] 2017-11-05 09:54:54 <java.lang.ref.PhantomReference@183d0bb4> (com.example.MyClass)
        r37c92c4@80c668d6 pool-15-thread-1] [INFO ] 2017-11-05 09:54:54 <java.lang.ref.PhantomReference@4b7f2f5f> (com.example.MyClass)
        r37c92c4@80c668d6 pool-15-thread-1] [INFO ] 2017-11-05 09:54:54 Total: 3

通过上面的代码堆栈信息,可以看到线程 A 在执行完逻辑后,没有释放 com.example.MyClass 类型的资源,导致系统产生了大量的 java.lang.ref.PhantomReference 引用,导致内存泄漏。

通过分析 jstack 信息,可以发现问题所在并以此解决问题。

以上就是输出 java 进程的 jstack 信息示例分享及通过线程堆栈信息分析 java 线程的完整攻略。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:输出java进程的jstack信息示例分享 通过线程堆栈信息分析java线程 - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • Spring Boot整合持久层之JPA多数据源

    让我来为你详细讲解“Spring Boot整合持久层之JPA多数据源”的完整攻略。 1. 环境准备 本文假设你已经安装了以下软件: JDK 1.8或更高版本 MySQL数据库 Eclipse或IntelliJ IDEA等开发工具 此外,还需要引入以下依赖包: Spring Boot Starter Data JPA MySQL JDBC Driver(如果你…

    Java 2023年5月20日
    00
  • SpringSecurity实现动态url拦截(基于rbac模型)

    下面是详细讲解 Spring Security 实现动态 URL 拦截(基于 RBAC 模型)的完整攻略: 1. 什么是 Spring Security Spring Security 是一个基于 Spring 框架的安全框架,提供了完善的身份认证和授权功能。 2. 什么是 RBAC 模型 RBAC(Role-Based Access Control)模型是…

    Java 2023年5月20日
    00
  • t01_idea消除的白框

    消除idea顶部窗口上的白色标题栏 点击Hlep,找到Edit Custom VM Options…点击 添加下面一段话(如果有责显示为false责改为true): -Dide.win.frame.decoration=true 然后重启即可,如下图所示,顶部白框已经没有出现了 原文链接:https://www.cnblogs.com/2580p/p/1…

    Java 2023年5月2日
    00
  • Java实现办公文档在线预览功能

    实现Java办公文档的在线预览功能需要完成以下步骤: 步骤一:选择合适的文件预览解决方案 Java实现办公文档在线预览功能需要使用第三方工具来解析文档文件,目前比较流行的解决方案有如下几种: LibreOffice:可实现对多种文档格式的解析,包括Microsoft Office文件,OpenOffice文件,PDF文件等等。 Aspose.Words:仅支…

    Java 2023年5月19日
    00
  • synchronized关键字如何保证线程安全?

    synchronized 关键字可以保证多线程环境下的线程安全。它可以用于修饰方法和代码块。 修饰方法 当一个 synchronized 关键字修饰的方法被一个线程调用时,该方法就会被锁定,以保证同一时间只有一个线程可以执行该方法,直到该方法执行完毕释放锁。下面是一个例子: public class ThreadSafeDemo { private int …

    Java 2023年5月10日
    00
  • Java 其中翻转字符串的实现方法

    要实现Java中字符串翻转,有多种方法可以选择,包括使用for循环、StringBuilder和递归等。下面将分别介绍它们的实现方法: 使用for循环 使用for循环实现Java中字符串的翻转,可以先将字符串转换成字符数组,再使用两个指针分别从字符串的开头和结尾向中间遍历,每遍历一次,则将两个指针指向的字符互换位置,最终完成翻转。代码如下: public s…

    Java 2023年5月27日
    00
  • java实现输出任意整数的每一位

    下面是java实现输出任意整数的每一位的完整攻略。 步骤一:将整数转成字符串 我们知道,字符串中每个字符都可以通过下标访问。所以,我们只需要将整数转换成字符串,就可以通过下标依次访问每个数字了。 int num = 123456; String numStr = String.valueOf(num); // 将整数转换成字符串 步骤二:遍历字符串,输出每一…

    Java 2023年5月26日
    00
  • Java 创建线程的两个方法详解及实例

    Java 创建线程的两个方法详解及实例 在 Java 中,创建线程有两种方法,一种是继承Thread类,另一种是实现Runnable接口。本文将详细介绍这两种方法并提供示例代码。 1. 继承Thread类 继承Thread类是一种创建线程的简单方法,只需要继承Thread类并重写run方法即可。 示例代码: public class MyThread ext…

    Java 2023年5月18日
    00
合作推广
合作推广
分享本页
返回顶部