jstack日誌分析

一、jstack日誌分析概述

jstack是一個Java虛擬機自帶的工具,可以生成Java線程轉儲文件(常稱為Java堆棧轉儲文件),輸出當前JVM內所有線程的堆棧信息。jstack日誌分析在調試Java程序時非常有用,可以用於檢查線程是否被鎖死,線程是否在等待請求響應等問題。通過jstack日誌分析,我們可以更好地定位問題,提高問題定位效率。

二、生成jstack日誌

生成jstack日誌的方法非常簡單,只需要執行以下命令:

jstack -l pid > jstack.log

其中,pid指的是Java進程的進程ID,jstack.log是生成的日誌文件名稱。

三、jstack日誌分析工具介紹

在進行jstack日誌分析時,有很多工具可以使用,下面我們介紹幾個常用的工具:

1. Eclipse MAT

Eclipse MAT是一款基於Eclipse的Java堆分析器,可以用於檢查Java線程狀態,分析Java堆狀態等問題。MAT可以處理Java堆轉儲文件,jstack輸出文件等等。

2. jstack解析器

jstack解析器是一款開源的Java工具,可以對jstack輸出的堆棧信息進行解析和分析,支持線程狀態分析、死鎖分析、線程間調用分析等等。

3. VisualVM

VisualVM是一個可視化的Java性能分析工具,可以用於監控Java應用程序的性能,並且提供了線程分析功能。可以通過VisualVM生成jstack日誌,並且可以對日誌進行分析。

四、jstack日誌分析示例

1. 線程狀態分析

jstack日誌中,每個線程都有自己的狀態,常見的線程狀態包括Runnable、Waiting、Timed_Waiting、Blocked、In_Object_Wait等等。通過分析線程的狀態,我們可以看到線程是否正在執行、是否被阻塞、是否在等待某個資源。

示例代碼:

"Thread-141" #1224 prio=5 os_prio=0 tid=0x00007f364804d800 nid=0x588b waiting on condition [0x00007f364ddbc000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at com.example.demo.service.TestService.testMethod(TestService.java:16)
        at sun.reflect.GeneratedMethodAccessor66.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)

2. 死鎖分析

在jstack日誌中,如果有線程被阻塞等待某個資源,而該資源又被其它線程所持有,則很可能發生死鎖。通過jstack可以分析死鎖線程,進一步了解死鎖產生的原因,從而解決問題。

示例代碼:

"Thread-1182" #1489 prio=5 os_prio=0 tid=0x00007fbf5c0e4800 nid=0x34f3 waiting for monitor entry [0x00007fbf3f3cf000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at com.example.demo.service.TestService.testMethod(TestService.java:26)
        - waiting to lock  (a com.example.demo.entity.TestEntity)
        at sun.reflect.GeneratedMethodAccessor72.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)

"Thread-1183" #1490 prio=5 os_prio=0 tid=0x00007fbf5c0eb000 nid=0x34f4 waiting for monitor entry [0x00007fbf3f2ce000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at com.example.demo.service.TestService.testMethod(TestService.java:26)
        - waiting to lock  (a com.example.demo.entity.TestEntity)
        at sun.reflect.GeneratedMethodAccessor72.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)

3. 線程間調用分析

jstack日誌可以展示線程之間的調用關係,對於分析代碼調用鏈非常有幫助。我們可以通過jstack日誌分析方法之間的調用順序,了解程序的執行過程。

示例代碼:

"Thread-1" #119 prio=5 os_prio=0 tid=0x00007ff1941d6800 nid=0x49c8 runnable [0x00007ff1986e7000]
   java.lang.Thread.State: RUNNABLE
        at com.example.demo.service.TestService.testMethod(TestService.java:16)
        at sun.reflect.GeneratedMethodAccessor66.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)

"Thread-2" #120 prio=5 os_prio=0 tid=0x00007ff1941d8800 nid=0x49c9 waiting on condition [0x00007ff1985e6000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for   (a com.example.demo.entity.TestEntity)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at com.example.demo.service.TestService.testMethod(TestService.java:24)
        at sun.reflect.GeneratedMethodAccessor71.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)

五、總結

通過本文的介紹,我們了解了jstack日誌分析的流程、常用工具和分析方法。在實際的開發中,我們可以根據具體的問題選擇不同的工具進行分析,可以更快地解決問題,提高開發效率。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/244826.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-12 13:04
下一篇 2024-12-12 13:04

相關推薦

  • Cron執行日誌用法介紹

    本文將從多個方面對cron執行日誌進行詳細闡述,包括cron執行日誌的定義、cron執行日誌的產生原因、cron執行日誌的格式以及如何解讀cron執行日誌。 一、定義 Cron是一…

    編程 2025-04-29
  • Hibernate日誌打印sql參數

    本文將從多個方面介紹如何在Hibernate中打印SQL參數。Hibernate作為一種ORM框架,可以通過打印SQL參數方便開發者調試和優化Hibernate應用。 一、通過配置…

    編程 2025-04-29
  • 如何通過jstack工具列出假死的java進程

    假死的java進程是指在運行過程中出現了某些問題導致進程停止響應,此時無法通過正常的方式關閉或者重啟該進程。在這種情況下,我們可以藉助jstack工具來獲取該進程的進程號和線程號,…

    編程 2025-04-29
  • 使用Snare服務收集日誌:完整教程

    本教程將介紹如何使用Snare服務收集Windows服務器上的日誌,並將其發送到遠程服務器進行集中管理。 一、安裝和配置Snare 1、下載Snare安裝程序並安裝。 https:…

    編程 2025-04-29
  • Log4j日誌打印到Systemout.log

    Log4j是Apache的一個強大的日誌組件,可以幫助開發者更好地管理日誌。在Java應用程序中,很多開發者都會選擇使用Log4j來實現日誌輸出。本文將介紹如何使用Log4j將日誌…

    編程 2025-04-28
  • 如何將Linux系統日誌發送到日誌服務器

    本文將介紹如何將Linux系統日誌發送到日誌服務器,以方便管理和監控系統狀態。 一、安裝rsyslog軟件包 rsyslog是Linux系統上默認的系統日誌軟件,用於收集系統事件和…

    編程 2025-04-27
  • SpringBoot如何設置不輸出Info日誌

    本篇文章將帶您了解如何在SpringBoot項目中關閉Info級別日誌輸出。 一、為什麼要關閉Info日誌 在開發中,我們經常會使用Log4j、Logback等框架來輸出日誌信息,…

    編程 2025-04-27
  • Mybatis-plus 日誌詳解

    一、日誌框架概述 1、什麼是日誌框架 日誌框架是一個用於管理日誌的工具,使用日誌框架可以幫助開發人員記錄程序運行時產生的信息、警告和錯誤消息。常用的日誌框架有log4j和logba…

    編程 2025-04-24
  • Python日誌記錄詳解

    在軟件開發中,日誌記錄是非常重要的一項功能。它可以幫助開發者追蹤程序的狀態,發現問題並進行調試。Python提供了很多模塊來處理日誌記錄,例如logging模塊。在這篇文章中,我們…

    編程 2025-04-24
  • log4cpp:多功能的C++日誌庫

    一、簡介 log4cpp是一個支持多線程的C++日誌庫,能夠讓程序員在應用程序中方便地記錄日誌輸出,分級管理日誌信息,並靈活地控制日誌記錄方式。 log4cpp的設計目標是提供一種…

    編程 2025-04-24

發表回復

登錄後才能評論