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

yizhihongxing

下面是详细讲解“输出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日

相关文章

  • 什么是栈区?

    以下是关于栈区的详细讲解和使用攻略: 栈区的作用是什么? 栈区(Stack)是一种用于存储方法调用和局部变量的内区域。栈区是线程有的,其大小可以通过 -Xss 参数进行设置。 栈区的使用攻略 使用栈区,需要注意以下点: 在程序发中需要合理使用内存,避免出现栈溢出等问题。 在方法调用过程中,需要注意方法的嵌套深度避免出现栈溢出等问题。 在方法中定义局部变量时,…

    Java 2023年5月12日
    00
  • SpringBoot JWT实现token登录刷新功能

    下面就为你详细讲解“SpringBoot JWT实现token登录刷新功能”的完整攻略。 什么是JWT JWT即Json Web Token,是基于JSON格式的令牌,包含有用户的一些身份信息和一些验证信息。在用户登录后,服务器会生成一个JWT给前端返回,在之后的请求中,前端只需在HTTP头中携带该令牌即可实现状态保持。 实现流程 首先,我们需要在项目中引入…

    Java 2023年5月20日
    00
  • js 判断登录界面的账号密码是否为空

    首先需要了解“js 判断登录界面的账号密码是否为空”这个问题的背景与目的。这个问题是指在前端页面中,需要判断用户输入的账号密码是否为空,以防止用户提交空的数据或者提交错误的数据,从而提高用户体验和系统安全性。 解决这个问题的核心思路是通过正则表达式对用户输入的内容进行匹配,判断是否为空。以下是具体步骤: 获取用户输入的账号和密码,可以使用document.g…

    Java 2023年6月16日
    00
  • 详解Spring Security 简单配置

    《详解Spring Security 简单配置》是一篇介绍如何简单配置Spring Security的文章。下面是详细攻略: 1. 引入依赖 首先需要在项目中引入Spring Security的依赖,可以从Maven Central Repository中搜索Spring Security依赖,选择适合的版本引入。 2. 配置Spring Security …

    Java 2023年5月20日
    00
  • springboot oauth2实现单点登录实例

    下面我将详细讲解如何使用Spring Boot OAuth2实现单点登录的完整攻略。主要分为以下几个步骤: 第一步:创建OAuth2授权服务器 在Spring Boot中实现OAuth2授权服务器需要通过添加spring-boot-starter-oauth2-server依赖来完成。具体实现步骤如下: 添加maven依赖 <dependency&gt…

    Java 2023年5月20日
    00
  • java Disruptor构建高性能内存队列使用详解

    Java Disruptor构建高性能内存队列使用详解 Java Disruptor是一个Java内存队列(Memory Queue)框架,其可以高效地实现并发数据交换,以及与其他多线程系统的数据交换。在高性能计算、高并发、大吞吐量等场景下能够发挥出非常好的性能。本文将详细介绍如何使用Java Disruptor构建高性能内存队列。 原理介绍 Disrupt…

    Java 2023年5月27日
    00
  • 类卸载的触发条件是什么?

    类卸载是指在JVM中,当一个类不再被引用的时候,就会被JVM卸载,释放其占用的内存资源。类卸载的触发条件与垃圾回收机制密切相关。 在JVM中,当一个类不再被引用时,会进入“可卸载状态”,但仅仅处于“可卸载状态”是不够的,还需要满足以下两个条件才能被卸载: 该类的所有实例都已经被回收,不存在任何活动的类实例; 加载该类的ClassLoader已经被回收。 只有…

    Java 2023年5月11日
    00
  • javascript正则表达式之search()用法实例

    JavaScript正则表达式之search()用法实例 简介 在 JavaScript 中,正则表达式是一个非常强大的功能。正则表达式用于对文本进行模式匹配和替换。search()方法是 JavaScript RegExp 对象的一个方法。search() 方法用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串。 语法 search() 方…

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