java 定位問題方法 (jdb 和 jstack)


 使用java 做開發,大部分的朋友都是利用DIE 來做debug 工作,因為這樣可視化效果好。

但是在真實的工作中,很多使用遇到問題,手頭或者環境是不允許你利用DIE 來對源碼做debug 工作,開發者只能夠利用僅有的jdk 環境和shell 環境,對出現問題的程序進行debug。

本篇文章主要是向大家介紹,如何利用jdk 自帶的 jdb 和jstack 來定位問題。

  • jdb 

首先jdb 是一款類似gdb 的工具,它可以幫助用戶在運行程序時,直接打對應斷點,然后進行debug 工作。

jdb 和IDE debug 的區別在於,整個debug 過程都是命令行交互的。

用戶使用jdb 進行debug ,有兩種方式

  1. 直接利用jdb 啟動程序
  2. 在啟動程序時,加入特殊參數,使得用戶可以通過 jdb attach 進去

我們先來看看直接使用jdb 如何debug 程序。

jdb 運行程序,其實和java 直接運行程序差不多,但是有一些小細節需要大家注意的,就是jdb 不支持-cp 命令,也不支持以下方式添加classpath

-Djava.ext.dirs="/root/monitor_collect/lib"

在使用jdb 運行程序時,如果有以來jar 包,用戶必須要使用 -classpath 參數,將相關的jar 全部填寫進去,例如一個完整的啟動命令

jdb -Dlog4j.configuration="file:/root/monitor_collect/log4j.properties"  \
-classpath /root/monitor_collect/lib/args4j-2.33.jar:/root/monitor_collect/lib/sequoiadb-driver-3.0.jar:/root/monitor_collect/lib/slf4j-api-1.7.12.jar:/root/monitor_collect/lib/log4j-1.2.14.jar:/root/monitor_collect/SdbMonitor.jar  \
com.sequoiadb.monitor.MonitorAlarm

進入jdb后,會顯示以下信息

Initializing jdb ...

然后用戶就可以開始debug 了,先打一個斷點。

打斷點有兩種方式

  1. 對某個類的方法打上斷點
  2. 對某個類的行號打上斷點

如果是對某個類的方法打斷點,命令是

stop in com.sequoiadb.monitor.alarm.util.AlarmObject.analy_transaction

如果是對某個類的行號打斷點,命令是

stop at com.sequoiadb.monitor.alarm.util.AlarmObject:944

注意:類名一定要寫全,包括package 名字也要寫好。

運行的命令為:run

查看當前運行的堆棧信息為:where

執行下一步為:next

打印某個變量為:print

進入該行的函數為:step

從函數中跳出來為:step up

讓程序從斷點中繼續執行為:cont

 

后面讓我們再來看看,如果利用java 程序啟動后,用戶通過jdb 連接並且調試的。

用戶在執行java 程序時,需要添加以下額外的參數,suspend=y 表示不加載主類,只有用戶通過 jdb connect 后,再加載主類。

-Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y

例如一個完整的命令:

java \
-Dlog4j.configuration="file:/root/monitor_collect/log4j.properties"  \
-cp /root/monitor_collect/lib/args4j-2.33.jar:/root/monitor_collect/lib/sequoiadb-driver-3.0.jar:/root/monitor_collect/lib/slf4j-log4j12-1.7.25.jar:/root/monitor_collect/lib/slf4j-api-1.7.12.jar:/root/monitor_collect/lib/log4j-1.2.14.jar:/root/monitor_collect/SdbMonitor.jar  \
-Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y \
com.sequoiadb.monitor.MonitorAlarm

用戶執行該命令后,窗口會掛起,用戶可以在另外一個窗口中,繼續操作(支持遠程連接),如果需要遠程連接,添加hostname 參數即可,如果hostname 參數不填寫,默認為本地

jdb -connect com.sun.jdi.SocketAttach:port=8787,hostname=sdb1

用戶通過 jdb connect 到遠程的jave 程序后,操作方式和直接使用 jdb 啟動程序的方式一致。

 

  • jstack

jstack 是jdk 又一個好用的debug 工具。它和jdb 不同,不是交互式地查看java 程序的相關調用和變量值,而是當用戶的java 程序在運行過程中,突然出現 handle 的情況,而且該情況無法 100% 復現時,用戶可以利用 jstack 工具將java 程序當前的堆棧信息全部打印出來。

這樣用戶可以通過堆棧信息分析程序到底是 handle 在什么地方。

 

jstack 打印java 程序當前的堆棧信息

jstack -l PID > java.jstack.out

 

 

參考博客:

http://blog.csdn.net/arkblue/article/details/39718947

https://www.ibm.com/developerworks/cn/java/joy-jdb/index.html

介紹jave 程序在啟動 jdwp 時,各種參數的含義:http://chainhou.iteye.com/blog/1837059


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM