天天看點

IDEA使用debug斷點調試技巧詳解(附帶gif動圖示範)

作者:java領域

前言

使用debug斷點調試是每個程式員的必會技能,我們每天的工作不就是寫bug,找别人的bug嘛!debug作為排查問題的一大絕殺技,斷點一打,問題分分鐘解決。再加上一些IDE的debug工具這麼好用,jdk自帶的jdb工具也能支援本地調試和遠端調試。妥妥的年度最佳工具,但是就我而言,平時排查問題就是打了個行斷點,條件斷點,雖然也能排查出大部分問題,但是總感覺使用的不夠 優雅~,而且對debug的過程也不清楚。

本文就來了解一下debug的原理和調試技巧。附帶git動圖示範,文中不會指出基礎的debug操作,隻列出一些使用技巧,相信你掌握了這些技巧,對debug的了解更進一步,排查解決問題的效率也必然上一個檔次。

debug原理概述

JAVA調試器的運作,是由JPDA(Java Platform Debugger Architecture)體系支撐起來的。引用官方文檔中的闡述,JPDA 是一種多層調試架構,開發人員可以建立調試器程式,而且這些調試程式可以跨平台、跨虛拟機、跨JDK版本運作。參考oracle的 官方文檔

JPDA is a multi-tiered debugging architecture that allows tools developers to easily create debugger applications which run portably across platforms, virtual machine (VM) implementations and JDK versions.

整個JPDA體系架構如下圖所示,分為三個部分:

IDEA使用debug斷點調試技巧詳解(附帶gif動圖示範)
  1. JVM TI(Java VM 工具接口) 是 J2SE 5.0 中引入的新接口,它取代了JVMDI。由C語言編寫,定義了VM提供的調試服務接口,用于擷取和控制目前虛拟機狀态。
  2. JDWP (Java 調試線協定) 由C語言編寫,定義了被調試者和調試器程序之間的通信資料格式。
  3. JDI ( Java 調試接口) 定義一個進階 Java 語言接口,調試工具的開發人員使用它來編寫調試器程式。IDEA的debug工具就是實作了這一套API,才為我們提供出來好用的工具。

Java遠端調試的原理是兩個VM之間使用JDWP協定通過socket進行通信,以達到遠端調試的目的,當我們在IDEA中以debug模式啟動運作類,就可以直接調試了,過程如下:

  1. IDEA用戶端和vm程式端 建立 socket 連接配接。使用JDWP協定。
  2. 将斷點位置建立了斷點事件通過 JDI 接口傳遞給服務端VM,VM調用suspend将VM挂起。
  3. VM 挂起之後将用戶端需要擷取的 VM 資訊傳回給用戶端,傳回之後 VM 恢複運作狀态
  4. 用戶端擷取到 VM 傳回的資訊之後可以通過不同的方式展示給使用者。

下面通過一個動圖,看一下IDEA以debug模式運作程式都做了哪些事,首先建立起雙向的通信,應用程式通過debug模式運作起來之後,可以通過jps看到啟動參數中多了一行,這就是聲明了使用jdwp協定,以及一些vm參數。

-agentlib:jdwp=transport=dt_socket,address=127.0.0.1:**55951**,suspend=y,server=n           
IDEA使用debug斷點調試技巧詳解(附帶gif動圖示範)

其實遠端debug也需要加上這段參數,如何進行遠端debug會在最後一個章節中提到,接下來列出一下常用的debug技巧。

斷點技巧

字段斷點

如果想要知道某個類的字段屬性在哪一行代碼被修改了值,就需要使用到字段監視斷點。需要注意的是字段監視斷點隻能打在類字段上,打在引用類型的對象或者集合類型上是不生效的。我們也可以為引用類型的對象屬性添加watch監視。

  • 字段監視斷點可以幫助我們定位到在哪一行被修改了。
  • 屬性watch可以幫助我們捋清楚變量值的變化過程。

如下圖所示,我們為變量a上打了一個字段監視斷點,debug運作時,則會停在改變a值得哪一行,我們也可以為這個a值添加watch,以觀察這個值變化鍊上的每一次值改變狀況。

IDEA使用debug斷點調試技巧詳解(附帶gif動圖示範)

方法斷點

當接口有多個實作時,當不知道程式執行走的是哪一個類的實作時,就可以将斷點打在接口中的方法上,那麼程式運作後可以直接步入到具體的實作類中的方法。

IDEA使用debug斷點調試技巧詳解(附帶gif動圖示範)

有時候不想在方法裡一步步執行,可以直接在方法簽名上打斷點,斷點會在方法的首尾行停留,配合上watch,我們可以看這個方法中究竟做了什麼,以及産生了哪些影響。

IDEA使用debug斷點調試技巧詳解(附帶gif動圖示範)

條件斷點

常用于多線程或者請求頻繁時,當不斷有請求調用目前方法時,我們可以設定條件斷點,滿足條件時,才會步入斷點行,然後對目前請求進一步調試。條件斷點怎麼打就不用多說了,右鍵斷點,添加條件判斷語句,隻有true和false兩種結果,條件是根據上下文寫的。

異常斷點

異常斷點在工作中也非常有用,就是因為遇到了異常才去調試程式,那怎麼能不用上異常斷點呢?平時看到長串的異常堆棧資訊,例如最常見的空指針異常,我們都是找到對應是哪一行爆出來抛出的異常,然後慢慢往下跟,找到具體為null的變量,才能找出導緻程式退出的根因。

IDEA的debug工具,提供的異常斷點,顧名思義,就是當遇到異常的時候,斷點會停在目前行,使用起來也非常簡單,隻需要添加進對應的異常類型,開啟異常斷點即可。如下圖在空指針異常時斷點。以供檢視上下文變量的值。

IDEA使用debug斷點調試技巧詳解(附帶gif動圖示範)

多線程斷點

當遇到多線程調試的時候也是個麻煩事兒,因為不知道目前到底是哪一個線程在運作中,是以就需要使用到線程debug了,也是結合條件斷點,根據線程名去斷下對應的線程。

IDEA使用debug斷點調試技巧詳解(附帶gif動圖示範)

Stream流斷點

大家常用的stream流,寫時一時爽,調試火葬場,因為屬于流操作,斷點無法跟蹤到内部,檢視相應的值變化,是以當stream複雜的時候,debug起來也是一件頭疼的事,但是idea中的跟蹤流鍊功能就非常實用了,他能顯示出每一步流操作的輸出結果。

IDEA使用debug斷點調試技巧詳解(附帶gif動圖示範)

遠端斷點

本地debug調試自然是簡單,但是一旦項目部署到伺服器上,沒有了本地環境,該怎麼調試呢?其實有辦法,線上的項目可以開啟遠端調試,如本文開頭所講,其實debug的原理就是兩個vm之間的socket通信,加上一串參數就好了,那麼我們也可以給線上的服務運作的JAVA_OPTS中加上這段參數,聲明好端口即可,例如:

-agentlib:jdwp=transport=dt_socket,address=127.0.0.1:9999,suspend=y,server=n           

服務端的vm啟動好之後,接着啟動用戶端的vm,當我們使用IDEA,可以建立一個remote jvm debugger的用戶端,用于attach到遠端jvm内部,過程如下所示,可以做到如同本地調試一樣,調試遠端服務了,但是需要注意的是本地的代碼一定要和線上運作服務的那一套代碼完全相同。

IDEA使用debug斷點調試技巧詳解(附帶gif動圖示範)

注意事項

  • 一般正式環境不會将遠端debug開啟,會有安全隐患。
  • 在測試環境遠端debug時會将整個vm挂起,是以服務處于不可用的階段,會影響到其他開發人員正常使用服務。
  • debug時間太長,可能會使vm宕掉。是以切記一定要及時關掉debug的用戶端。

如果本文對你有幫助,别忘記給我個3連問 ,點贊,轉發,評論,

學習更多JAVA知識與技巧,關注與私信部落客(08)學習JAVA 課件,源碼,安裝包,還有最新大廠面試資料等等等

咱們下期見。

收藏 等于白嫖,點贊才是真情。

繼續閱讀