先看下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”
详细展开各个说明
双引号里的是线程名字,以后@,以后线程ID,以后in group,以后是这个线程归属的组的名字,以后是线程的状态。如:当前线程名是Thread-0,线程ID是477,在名为main的线程组里,RUNNING状态。
有些线程没有 “组” 的信息,如不知道Finalizer是哪一个组的,这多是比较基础的线程,因此就没有。
线程组是为了好维护一堆的线程,线程组下面有线程,也能够挂着其余组。
可看打钩下面的,是追踪点。蓝色底的是debug停住的地方(断点或者光标),能够发现
(光标也能够跟断点同样停住)
可发现,其实上述就是一个debug的跟踪链。
越靠近上面是 “近”,越下面越是 “源头”
每一行是一个跳点
(所谓的跳点,其实就是从一个方法跳到另一个方法的接触点)
(PS:跳点的词是自创。。。专业的叫什么? 入栈点? 进入一个方法叫入栈,出来方法叫弹栈)
总的来讲,这个图是一个跟踪链,从main方法16行,致使了getString的调用,在getString的11行致使了myMEthod的调用,在myMethod的10行就是debug停住的地方。
快速回到最后断点的位置:双击Frames最上面一行
快速回到断点的位置:双击Frames想进入的那行
有时候Frames的方法名是 <init>
,表示的是类的初始化,即把断点打在类上,停住时显示的内容
这个面板显示了项目的全部断点
断点种类和特性:
行断点(line breakpoints)
即打在代码行的
类断点(官方没这个说法,是我加的)
打在类上的断点。跟行断点同样,也是出如今
Java Line Breakpoints
分类中;圆形。(类断点在debug时也是能够停住的,new的时候,静态方法调用不停!)
方法断点(method breakpoints)
是打在方法上的
Java Field Breakpoints
打在字段上行的断点。当字段的值被改变时,断点会停在改变处(经过反射获得字段并进行改变则不会停下)
异常断点(Java Exception Breakpoints)
发生异常的时候要停下来的断点(图示是闪电标记)
JS异常断点(JavaScript Exception Breakpoints)
估计就是拦截js异常的断点,应该是自动监控的
断点的形状、颜色
见图,不一样种类的断点、不一样状态的断点的图示是不同的。好比圆形、菱形、眼状、闪电状、红色、黄色、问号表示有Condition。其中打在类上的断点的图示和行断点如出一辙
疑惑
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,想要就打勾。默认状况下,彷佛Threads、Memory、Overhead都没有启用
Restore Default Layout:恢复默认,就是你不当心把某些layout关闭了,或显示尺寸调乱了,用这个恢复
若是你找不到你的layout:Watches,可能用Restore也恢复不了。耐心找找,文字很难描述清楚这种状况。
强调:若是有个方法打了断点,被直接调用,或者是经过反射被调用,都是会停下的。
虽然反射有点像空气同样,那也仍是得经过jdk的一些类调用进入的,不会凭空进入
这个调试技巧也很重要:即某个字段的值是什么时候赋值的。本文提到了,请详细查阅。
Drop Frame
这个是很是强大的功能,是后悔药。对当前方法重来一遍
如图的例子,
t2.test1();
停住时,是不能按Drop Frame的,此时还在主干main线程。注意:可能须要注意一点,这个 “后悔药”,让你再运行一次,以本代码为例,若是在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,按理说应该一路通畅,可是却在花括号结束处停住了,问题我在 }
没打断点,为何停在那边?
这个我暂时也不能彻底理解。只是知道多是相似把断点打在方法声明上(方法断点),运行到结束时,即便结尾没有断点,它都会停一下。多是相似的机制吧