9个服务端提升debug效率的IDEA Debugger技巧(下)

简介: 9个服务端提升debug效率的IDEA Debugger技巧(下)

更多精彩内容,欢迎观看:

9个服务端提升debug效率的IDEA Debugger技巧(上):https://developer.aliyun.com/article/1263219?groupCode=taobaotech



渲染


▐  修改对象渲染器


  • 使用场景


有时,IDEA自带的变量渲染器并不能满足我们的需要。例如,我们创建一个继承JSONObject的类:


由于JSONObject继承了Map,所以IDEA默认是以Map的方式渲染的,因此,当我们运行以下代码时:


可以看到Debugger将bizObject渲染为了:


可以看到,bizObject中的msg字段直接不见了,这当然不是我们想要的,为了获得真实的变量结果,我们可以手动修改IDEA的渲染方式,以下提供三种方法。


  • 简单修改


直接将Map渲染器修改为toString渲染器即可


修改后,Debugger的界面就会变为:


该方法在一般情况下已经能够满足我们的需求。

  • 创建Class Level Watch


如果我们只想看BizObject中的msg字段,又不想修改渲染器的话,可以通过创建Class Level Watch来达到这一目的。

右键变量,点击New Class Level Watch


在弹出的输入框中输入想要查看的内容:

接下来,项目中所有类型为BizObject的类都会单独渲染一个msg字段。

  • 创建自定义渲染器


如果上述方案都不能满足我们花哨的需求,也可以自定义渲染器:在指定的对象上,选择Create Renderer


在渲染器创建页面中,我们可以自定义渲染方式:


当保存后,就可以看到IDEA按照我们想要的方式渲染对应类型变量了:


如果渲染比较耗费资源,也可以勾选下面的On-demand开关,打开后,只有点一下对应变量才会执行渲染。

此外,如果想要将渲染配置同步给别人,也可以将配置抽取为注解放在对应类名上:


import org.jetbrains.annotations.Debug.Renderer;@Renderer(text = "name",childrenArray = "courses.toArray()",hasChildren = "courses.isEmpty()")public class Student {private String name;private ArrayList courses;Student(String name, ArrayList courses){this.name=name;this.courses=courses;}}


由于这一功能不是很常用,因此本文不再赘述,这里是注解说明https://www.jetbrains.com/help/idea/customizing-views.html#renderers

▐  修改列表渲染器


当我们创建如下的列表时:

在Debug界面,IDEA会将integers列表渲染为:

可以看到,IDEA并没有渲染为null的元素,如果我们没有注意,并在接下来遍历这个list,很可能会产生NPE。


如何让IDEA显示为null的元素呢?方法如下:

取消勾选后,IDEA就会将列表重新渲染为以下内容了。


定位


▐  标记


在一次请求链路中,有些对象在构造好后是不会轻易改变的,他们可能辗转穿梭于多个上下文中(例如User对象)。如果我们想要持续跟踪这个对象,则可以使用IDEA中的对象标记功能。


例如,我们创建两个上下文,分别为InputContext和OutputContext,其中都包含user字段。


在一次处理中,代码从inputContex中获取user放到outputContext中


在我们进入断点后,可以在user对象上选择Mark Object:

选择后,可以输入对于这个对象的标记(下例中将user用“mark”标记):

一旦一个对象被标记,这个对象在被销毁前就有了以下功能:

  1. 在任何debug页面,只要有引用指向这个对象,则会额外标记:

  2. 在任何线程,任何上下文中,我们都可以引用这个对象。

以下是一个在条件断点中引用user对象的实例:


在上图中,可以看到,process2方法的上下文中并没有被标记的user对象,然而,如果我们使用标记名_DebugLabel,就可以访问之前标记user的对象,并且能够取出其name字段。

注意:变量标记在当前Debug结束后就会失效。

▐  引用


在多线程环境下,如果一个对象同时被两个线程执行写操作,很可能会出现线程并发问题,如果我们定位到一个对象可能出现了多线程问题,要如何知道这个对象被哪些线程引用呢?


方法也很简单,只需要找到对应变量,点击Show referring Objects,就可以找到所有线程中引用当前对象的对象。

▐  异步栈信息


当我们在同步代码中使用线程池来执行异步任务时,这个异步任务的栈和主线程是隔离的,此时,IDEA还可以看到主线程的栈信息么?


例如以下代码:main方法中创建了一个异步任务,调用了task方法;在task方法中,又启用了一个异步任务,调用了innerTask方法。

通过实践可以发现,虽然是有两层的异步调用,但是IDEA还是打印出了包括主线程在内的所有堆栈信息:

只是每个Stack Frame之间增加了Async stack trace的提示,这是由于IDEA默认开启了Async stack trace,如果不想要看到除当前栈外的信息,可以在此处关掉这一功能:

关掉后,所有异步任务就只会显示当前的栈信息了。

相关文章
|
2月前
|
Java 内存技术
IDEA工具debug的小技巧
IDEA工具debug的小技巧
31 0
|
2月前
|
Java
IDEA debug HashMap源码的心得
IDEA debug HashMap源码的心得
26 0
|
22小时前
|
Java
idea远程debug应用
idea 中debug现场部署的Java应用
4 1
|
28天前
|
Java Spring
idea Spring-boot 项目debug启动过慢 spring debug启动过慢解决办法:已解决
idea Spring-boot 项目debug启动过慢 spring debug启动过慢解决办法:已解决
33 3
|
4天前
idea远程调试debug
配置idea远程debug
7 0
|
20天前
|
监控 前端开发
IDEA Debug技巧大全,看完就能提升工作效率
IDEA Debug技巧大全,看完就能提升工作效率
17 0
|
2月前
|
Java
IDEA DeBug
IDEA DeBug
22 1
|
2月前
|
Java 测试技术
使用IDEA进行服务器远程debug调试
使用IDEA进行服务器远程debug调试
49 0
|
2月前
IDEA远程调试Remote Debug
IDEA远程调试Remote Debug
31 0
|
2月前
|
监控 应用服务中间件
idea debug模式启动Tomcat报错:Error running ‘tomcat8‘: java.net.SocketException “socket closed“
idea debug模式启动Tomcat报错:Error running ‘tomcat8‘: java.net.SocketException “socket closed“