IDEA 2019 debug 技巧

IDEA 2019 debug 技巧

1、debug初识

先看下IDEA 2019 里的 debug 界面java

在这里插入图片描述

一、Debugger:debug的面板,查看各种东西web

二、Console:控制台,查看日志spring

三、Show Execution Point:单击后跳到这次debug最后执行位置。方便你一顿操做后不知道如今执行到哪一个点了。固然,点击Frames最顶那行,也能回到最后位置。springboot

四、Step Over:下一步(遇到调用方法不进入)框架

五、Step Into:进里面(若是同行有多个能够进入的,会让你移动光标选择进入的方法)编辑器

六、Force Step Into:强制进入下一步,无论是什么方法,即便是jdk封装的方法,也会进入ide

七、Step Out:跳出方法svg

八、Drop Frame:这是个很是高科技的按钮,是后悔药。详细在后面的调试技巧里讲测试

九、Run to Cursor:运行直到停在光标处(前提是光标前方无断点),方便的功能,能够不打断点停住lua

十、Evaluate Expression:计算表达式的值,跟watch不一样,这是临时的

十一、Trace Current Stream Chain:未知

十二、Frames:栈的相关信息,如线程信息,调用链。详情见后 “Frames”

1三、线程的信息,打钩是当前线程,下拉能够看到其余线程信息。详情见后 “Frames”

1四、调用链的信息,指示是怎么调用到当前断点的,双击能够进入对应的代码。详情见后 “Frames”

1五、Return:从新跑一遍debug

1六、Resume Program:眼睛一闭运行,直到结束或者遇到下一个断点

1七、Pause Program:未知,没用过,不重要

1八、Stop:中止debug

1九、View Breakpoints:查看全部断点。详细请看后面的 “View Breakpoints”

20、Mute Breakpoints:静音全部断点。能够这么用:不想再在以后的断点中停住,能够点击该按钮运行剩下的代码

2一、Get Thread Dump:未知,看名字就是获得线程的Dump文件,能够分析内存状况吧

2二、Settings:作一些配置。详细见后续 “Settings”

2三、Pin Tab:钉住最前。彷佛没什么用,历来不会被遮挡呀。

2四、Watch的面板:展现表达式的值的面板,比起Evaluate Expression,能够长久出现,不像Evaluate是临时性查看,下一次debug就没了

2五、New Watch:新增watch表达式:能够不在debug过程增长的,也能够右键选择表达式后Add to Watches(这个菜单只有在debug过程才会出现)

2六、Remove Watch:删除watch表达式

2七、Move Watch Up:上移调序

2八、Move Watch Down:下移调序

2九、Duplicate Watch:复制一份

30、Show watches in variables tab:在变量的tab页中显示watch表达式。非debug的状态下点击这个图标彷佛无反应,只有debug时你会发现变化

3一、Layout Settings:设置layout,所谓layout就是那些小面板。能够增长想要的layout,本身搞乱了layout也能够恢复默认。详细见后续 “Layout Settings”

详细展开各个说明

一、Frames

在这里插入图片描述

1)线程信息:
  • 打红色钩的,是当前线程
  • 非打钩的,是其余线程
2)详情信息:

双引号里的是线程名字,以后@,以后线程ID,以后in group,以后是这个线程归属的组的名字,以后是线程的状态。如:当前线程名是Thread-0,线程ID是477,在名为main的线程组里,RUNNING状态。

有些线程没有 “组” 的信息,如不知道Finalizer是哪一个组的,这多是比较基础的线程,因此就没有。

3)线程组:

线程组是为了好维护一堆的线程,线程组下面有线程,也能够挂着其余组。

在这里插入图片描述

可看打钩下面的,是追踪点。蓝色底的是debug停住的地方(断点或者光标),能够发现
光标也能够跟断点同样停住

  1. 当前位置,在名叫Stack02的类的myMethod方法的第10行(这个类的包名是com.wyf.test.ideadebug
  2. 致使代码运行到这里的,是上一个 “跳点”,即getString方法第11行
    点击getString那行,进入的不是getString方法的开始,是getString里头的 "跳点"
  3. 再往上跟踪,源头是main方法的第16行

可发现,其实上述就是一个debug的跟踪链。

  • 越靠近上面是 “近”,越下面越是 “源头”

  • 每一行是一个跳点

    所谓的跳点,其实就是从一个方法跳到另一个方法的接触点
    (PS:跳点的词是自创。。。专业的叫什么? 入栈点? 进入一个方法叫入栈,出来方法叫弹栈)

总的来讲,这个图是一个跟踪链,从main方法16行,致使了getString的调用,在getString的11行致使了myMEthod的调用,在myMethod的10行就是debug停住的地方。

4)技巧
  • 快速回到最后断点的位置:双击Frames最上面一行

  • 快速回到断点的位置:双击Frames想进入的那行

5)其余补充

有时候Frames的方法名是 <init>,表示的是类的初始化,即把断点打在类上,停住时显示的内容

在这里插入图片描述

二、View Breakpoints

在这里插入图片描述

这个面板显示了项目的全部断点

常见操做
  • +:新增。能够看到有各类各种的Breakpoints
  • -:删除
  • Group by Package:左起第三个按钮。这个package不知道是什么意思,好像也不是java的 “包”
  • Group by file:按文件分类,有时候能够方便找到断点位置
  • Group by Class:按class分类,方便找到断点位置
其余补充
  • 断点种类和特性:

    • 行断点(line breakpoints)

      即打在代码行的

    • 类断点(官方没这个说法,是我加的)

      打在类上的断点。跟行断点同样,也是出如今Java Line Breakpoints 分类中;圆形。(类断点在debug时也是能够停住的,new的时候,静态方法调用不停!

    • 方法断点(method breakpoints)

      是打在方法上的

    • Java Field Breakpoints

      打在字段上行的断点。当字段的值被改变时,断点会停在改变处(经过反射获得字段并进行改变则不会停下)

    • 异常断点(Java Exception Breakpoints)

      发生异常的时候要停下来的断点(图示是闪电标记)

    • JS异常断点(JavaScript Exception Breakpoints)

      估计就是拦截js异常的断点,应该是自动监控的

  • 断点的形状、颜色

    见图,不一样种类的断点、不一样状态的断点的图示是不同的。好比圆形、菱形、眼状、闪电状、红色、黄色、问号表示有Condition。其中打在类上的断点的图示和行断点如出一辙

  • 疑惑

    • 断点的状态这么多,既然能够删除断点,也能够不删而临时disabled,为何还要有suspend状态。
    • 类断点:打在类名那行的断点,在静态调用的时候不会停住,在new这个类时会。感受比较有趣,在这里提下
    • 方法断点,一般打了方法断点,会在启动springboot时被提示以下,建议你取消,那方法断点存在的意义是什么? (方法断点能在方法结束后即便不打断点也会停下来,算不算它存在乎义?)

在这里插入图片描述

三、settings

在这里插入图片描述

  • Show Values Inline:以下效果,在代码的右边显示变量的值,确实很方便

    在这里插入图片描述

    多说一句,阿里的Java代码规范不建议使用行注释,实际测试,在debug时会挤占变量值空间,这多是缘由

在这里插入图片描述

  • Show Method Return Values:以下效果

    在这里插入图片描述

  • Auto-Variables Mode:未知其功能,自行研究

  • Unmute Breakpoints on Session Finish:就是在debug结束后,恢复不静音。、

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HhJlwh6X-1583991955079)(/Users/stonewang/Library/Application Support/typora-user-images/image-20200311133351083.png)]

四、Layout Setttings

在这里插入图片描述

  • 分割线以前的是可选的 layout,想要就打勾。默认状况下,彷佛Threads、Memory、Overhead都没有启用

  • Restore Default Layout:恢复默认,就是你不当心把某些layout关闭了,或显示尺寸调乱了,用这个恢复

    • 若是你找不到你的layout:Watches,可能用Restore也恢复不了。耐心找找,文字很难描述清楚这种状况。

      在这里插入图片描述

2、调试技巧

强调:若是有个方法打了断点,被直接调用,或者是经过反射被调用,都是会停下的。

虽然反射有点像空气同样,那也仍是得经过jdk的一些类调用进入的,不会凭空进入

这个调试技巧也很重要:即某个字段的值是什么时候赋值的。本文提到了,请详细查阅。

一、技巧

  • Drop Frame

    这个是很是强大的功能,是后悔药。对当前方法重来一遍

    如图的例子,

    1. t2.test1(); 停住时,是不能按Drop Frame的,此时还在主干main线程。
    2. 点击Resume Program时,进入test2,咱们一顿调试,越过了for循环,此时咱们想从新看看v的值,可是v是过了花括号就看不见了。此时咱们须要后悔药,点击Drop Frame,回到test2方法被调用的地方(即test1那里)

    注意:可能须要注意一点,这个 “后悔药”,让你再运行一次,以本代码为例,若是在for循环里进行了入库操做或向mq发消息,那再执行一次,是否是会重复执行呢? 应该是会的

在这里插入图片描述

  • 新增watch表达式

    Evaluate好用,可是只有一次,能够新增表达式到watch,则可永久查看。

    选中表达式,而后Add to Watches 进行添加(该菜单只有在debug时才出现)

  • 调试时临时改变变量值

    如图,第一次打印是hello的值,截止停在第二次打印,咱们在Variables的layout里右键选中Set Value,设置后就打印出新值了

    在这里插入图片描述

  • 远程调试

    用本地代码,调试远程的程序。

    远程程序须要开启权限。另外远程部署的程序的代码,要和本地的一致,否则调试时行数对不上。详细配置方法搜索

  • 给断点设置条件,知足条件的时候才会停住

    设置好后,断点图标有个问号

在这里插入图片描述

在这里插入图片描述

  • 堆栈信息的查看方法

    上面对 Frames的layout也讲了一些知识点。这里再补充一些。

    • 最上面是当前断点位置,单击后进入当前运行的位置

      不必定是断点的位置,好比你在断点位置继续运行了一行,点击后就回到运行所在行,不是断点所在行。下面依次是调用链,展现了如何一步步运行到当前的。

    • 点击漏斗(Hide Frames from Libraries)能够过滤jar包里的方法

      好比过滤掉各类框架的,固然你本身写的类若是是在jar包里,也是会隐藏掉的。另外注意到一个细节,Frames里灰色的是jar包里的,黑色的是非jar里的(下图选中状态那行是非jar的代码,其实是黑的,看不出黑不黑)

    • 放心调试,某个方法A,无论A是被直接调用仍是经过反射调用,你打断点,都是会停住的,天然也会显示在Frames列表里

    在这里插入图片描述

  • 若是一个类或者接口,有不少子类,我怎么知道接下来执行到哪一个子类了呢?

    若是光看代码是比较麻烦的,可是debug时能够断点,停了以后看它真正的类是什么就可确认。或者你可使用step in。

  • 【重要技能】我怎么知道某个成员变量的值,在什么时候被赋值,被谁赋值?

    • 能够在变量中打断点,即 Java Field Watchpoints,若是变量值被改变就会在 “赋值的地方” 停下来,赋值处,好比setter方法,该setter无需打断点,只要变量打了断点。(可是,可是,可是,经过反射将字段值改变的,不会停下来)

    • 通常若是有setter,能够在setter打断点,停住后跟踪堆栈(很差用,PASS,有些赋值不经过setter,例如类内部的方法访问时直接对该变量赋值。有些是经过反射将值set进的)

    • 对于field watchpoints,默认只有变量值被改变时才会触发,对于访问该变量不触发,以下access

      在这里插入图片描述

  • 【操做技巧】右键编辑器里的断点,便可快捷操做断点

    在这里插入图片描述

  • 善用方法断点

    以下在类上打断点,会在进入方法的时候停住,而后点击Resume Program后并非直接运行出去,会在出去方法前停住。(以下,不管方法有没有返回值,都会在进入和出去的那行停住,有分支的根据具体的条件如flag的值停在return "if"/return "else"

    在这里插入图片描述

  • 善用异常断点

    异常断点不能直接在编辑器添加,要在View Breakpoints面板添加,能够指定拦截指定异常,或者全部异常。当发生异常的时候,会在产生异常的地方停下,有利于分析异常时的变量状况。

    • 添加步骤,在View Breakpoints->+号,如图

    • 异常拦截规则,跟catch同样,好比你监控的是NPE异常,可是实际抛出ArithmeticException,则不停断点;若是你监控IOException,除了IOException,它的子异常FileNotFoundException也是能停断点的;注意Any Exception,彷佛会拦截不少奇怪的异常,如IDEA加载时的异常,如

      在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 停在光标处

    能够免去打断点,点击 Run to Cusor,会运行到光标处(至关于在光标处打了断点)

  • step into

    以往运行主干要进入某个方法的分支,都跑进入打断点,其实很麻烦,用这个step into就好了

  • step out

    跳出某个方法回到上一层调用处。好像有时候 “跳不出来”。会产生这样的错觉是由于

    以下面的例子:先停在t2.test1();,接着Resume Program到达test2停住,这时候点击step out,并非回到main方法里,而是test1()里,这就是为何咱们老是以为step out好像跳不出来,总以为我没有进入过test1怎么会回到这里,由于已经进入了不少层了,它只能跳出上一层。这时能够一层层跳,老是会跳到最初的main方法里的。

    (咱们常常调试spring的代码,step out就回到了不少的相似代理的地方,总之以为乱七八糟的代码)

    在这里插入图片描述

  • 【长时间的疑惑】为何有时候会发现,我按下Resume Program,按理说应该一路通畅,可是却在花括号结束处停住了,问题我在 } 没打断点,为何停在那边?

    这个我暂时也不能彻底理解。只是知道多是相似把断点打在方法声明上(方法断点),运行到结束时,即便结尾没有断点,它都会停一下。多是相似的机制吧