关于eclipse:最好的IDEA-debug长文看完我佛了

3次阅读

共计 12505 个字符,预计需要花费 32 分钟才能阅读完成。

你好,我是 A 哥(YourBatman)。

最近写了几篇 IntelliJ IDEA 系列的文章,反应蛮好。我想了下,因为并非是分享什么破解办法、举荐插件、主题这种蛋炒饭式哗众取宠的文章,而是实在对工作有帮忙,对进步工作效率很有用的内容。同学们对应用 IDEA 还是有不少痛点,或者姿态不够正确优雅,始终以来 A 哥保持写些不同流合污、有肯定深度专栏文章,哪怕只是个工具 IDEA 而已。

上篇文章 文末做了阐明,本打算 IDEA 系列告一段落,但有收到几条上百字的留言和私信,感觉有些读者的确很用心在看,所以决定宠粉再干几篇。对于 IDEA 系列,工具嘛,钻研原理没有意义,而是站在使用者的角度,介绍正确姿态和最佳实际,用工具提效是惟一目标。

当然,也有私信问我我的主题咋设置的挺难看?用了哪些好用的插件?自定义的插件如何开发?之类的,我认为这种的确没必要独自分享喽,因为用谷歌百度一下就能够找到一推拉,各行大佬写的文章多了去了

本篇介绍 IDEA 调试 debug,因为它的确很重要。会不会 debug,有没有 debug 的意识,懂不懂 debug 的技巧,是有没有入门编程的重要标记。 对于 IDEA debug 调试的文章我在 CSDN 里早已发表过,反应还不错(看来有痛点的人不少呀):

明天我就把它“搬过去”,并做“加强”改变分享进去,心愿你喜爱。

本文提纲

版本约定

  • IntelliJ IDEA:2020.3.2

小插曲:IDEA 刚公布了其 2020.3.2 这个小版本,启动图换成了 20 周年 图,IntelliJ IDEA 20 周岁啦,为期 2 天的周年庆流动对开发者收费凋谢,感受一下:

注释

Debug 调试对 IT 从业者不是个生疏概念,工作中常常会用到它,这无关乎于高级、中级、高级程序员。调试程序的形式有多种,如:输入日志、减少辅助变量、拆分函数体、断点调试等等,本文将介绍的是 断点调试 — 一种最卓有成效的调试办法。精确的讲,本文讲述是应用 IntelliJ IDEA 断点调试。

Debug 用来追踪代码的运行流程,通常在程序运行过程中出现异常时,启用 Debug 模式能够剖析定位异样产生的地位,以及在运行过程中参数的变动。除此之外,咱们也能够应用 Debug 模式来跟踪代码的运行流程来学习优良的开源框架。

断点调试有多重要?

俗话说 编码 5 分钟,debug2 小时,从这句话就能体现出调试的重要性,毕竟它占据你“大部分”的工夫。

为了实在的体现出它的重要性,我“旁征博引”,找来了几个资深行业教训的大佬用援用他们的话来表述:

  1. 调试技巧比编码技巧 更为重要,因为破费在调试上的工夫往往比编码还多,学到的货色比编码中学到的更丰盛
  2. 调试技能重要性甚⾄ 超过 学习⼀门语⾔
  3. 不会调试的程序员,必定 编制不出任何好的软件

我把关键词都加粗划重点了,其重要性可见一斑。大佬尚且这么认为,何况是我等?所以,本文好好浏览 O(∩_∩)O 哈哈~

什么是断点?

忽然被这么一问,是不是脑袋懵懵的?

一个天天都在用的“货色”,若是真要你对它下个定义说给他人听,预计一时半会还解释不清。当然喽,大道至简,体会其要义能纯熟应用才是硬道理。本文作为一篇“庄重”的技术文章,天然须要先把断点这个概念用文字描述进去。

断点 :为了调试而 成心 让程序暂停的中央。它是一种附加在 源代码下面 的非凡 标记 ,在 debug 模式下能够触发 特定动作,如暂停执行、打印线程堆栈、计算表达式的值、变量跟踪等等。断点的设置和勾销全人为手动治理,若不手动解决(删除)将会和我的项目始终存在。

如果你看过前两篇文章,肯定能解释为何它会始终存在我的项目里。倡议你返回参阅,电梯中转

可见,断点的外围要义是暂停程序,从而在暂停那时刻就能够看到上线文的变量状况、IO 状况、线程状况等信息,进而更深刻的理解程序,及时发现问题和追踪到谬误的本源。

断点参数

断点并不是孤立存在的,它也能够有参数,从而定制出不同的断点行为,让其能在不同条件下失效,这个参数就叫 断点参数

咱们平时用得比拟多的 条件断点,它就是断点参数的最典型利用。当然除了条件断点,其它的断点类型也是能够定制化参数的。那到底有哪些断点类型能够应用和定制呢?那么接下来就步入到本文主体内容,开始进入更有意思的局部啦。

断点的根本应用

应该没人不会打断点吧,即便你是产品经理(产品经理莫名躺枪,手动狗头~)。

打断点最简略最间接的形式就是在你想设置断点的哪一行代码的 最右边窗栏 鼠标左键单击一下,实现后能看到一个小红点,就示意断点设置胜利啦,再点击一下就勾销。形如这样:

因为我的 IDEA 界面简洁,尽可能的去掉了“按钮”,所以平时我本人是应用到大量的快捷键来操作 IDEA,打断点也是如此常常用快捷键去实现。当然喽,很多时候也用鼠标的啦,毕竟鼠标解决还是有其很大劣势的。

阐明:我的快捷键是 Ctrl + Shift + B,仅供应你参考

治理断点

治理断点包含新增、删除断点。

对于大量断点来讲,鼠标一个个的点击给它删除掉是能够的。但若打了“大量”的断点在代码里(比方看 xxx 源码的时候),这时让去一个个找来删除是不太事实的,毕竟你可能本人都忘了哪儿有断点。这个时候一个治理页面 / 窗口就显得分外的重要了,在 IDEA 中提供了这样的窗口,你有多种形式关上它:

  1. 菜单栏形式:Run -> view breakpoints,毛病是门路太长太麻烦
  2. Actions 形式:双击 shift 调出 Actions 窗口,输出 view breakpoints 即可关上
  3. 任意断点处鼠标右键:抉择 more 即可关上治理窗口。毛病是:你至多得找到一个断点作为抓手(当然喽你能够任意处随便打一个点进去也成)
  4. 调试窗口:该打开方式上面会提到
  5. 快捷键形式:毫无疑问,这是我最为举荐的形式喽

在这个治理页面,你能够对断点进行 增删改

阐明:我的快捷键是 Ctrl + Shift + F8,仅供应你参考

如何 debug 模式运行?

额,这讲得是不是有点过于简略了点。

启动 Debug 模式运行的形式有多种,比方工具栏的虫子小图标按钮、程序办法入口左键点击、菜单栏、右键菜单栏等等,上面简略演示下:

据我理解,很多同学最罕用的形式是点击上方工具栏右上角的 虫子图标,因为我“没有”这个图标,所以“教程”中就不演示了。A 哥平时 99% 状况下都是应用快捷键形式启动程序,因为我认为那是最迅速和便捷的(当然不肯定适宜你)。

此性能我的快捷键分为两大类

  1. 运行右上角以后选中的入口类。它有一组快捷键

    1. Ctrl + Shift + Alt + enter:Run 运行
    2. Ctrl + Shift + Alt + \:Debug 运行
  2. 因为很多时候须要从 新的入口 启动程序,做 Spring Boot 工程开发可能领会不到(入口只有一个),但在做教程、Demo 的时候程序入口是常常变动的,所以不可能每次都还人肉去改启动类,效率太低。为此我就新设置了这组快捷键

    1. Ctrl + Shift + Alt + [:Run 运行,鼠标焦点所在 作为入口
    2. Ctrl + Shift + Alt + ]:Debug 运行,鼠标焦点所在 入口

另外,若要辨别本次是 Run 运行还是 Debug 运行,除了看右上角小虫子图标外,更好的形式看底部控制台窗口激活的是哪个。这样看的长处是:即便同一份利用启动屡次,也能疾速看进去哪些 debug 哪些 run。

值得一提的是:debug 模式运行,若没有任何断点被激活(比方你压根就没打断点),成果和 run 模式启动是一样(但控制台窗口不一样,因而日志输入的地位也就不一样)。

调试窗口详解

调试窗口是咱们断点调试的 操作面板,纯熟的应用此面板推提高效率和把握更多技巧十分重要。先来意识下它:

此操作面板上按钮不少,对 Debug 调试有多纯熟很大水平上是由操作此面板的熟练度决定的。

调试按钮

最罕用的一排按钮,入门必备。

一共 9 个按钮,从左往右顺次解释下:

Show Execution Point:回到以后激活的断点处。成果:若你鼠标当初在别的页面 / 别的类下面,点击它疾速“归位”

Step Over 步过:也叫单步调试,一行一行往下走,若这一行是办法也不会进入外面去。这个应该是平时应用得最多的按钮了,没有之一。所以,倡议记住你的快捷键来提高效率哈

Step Into 步入:进入办法体外部。这里的办法指的你自定义的办法 or 三方库的办法,不会进入到 JDK 官网的办法里(如下面的 System.out.println()这种它是不会进去的)

Force Step Into 强制步入:能进入任何办法,包含 JDK 的。个别查看底层源码才会用到它

Step Out 步出:它是搭配(Force) Step Into 一起应用的,当通过 step into 进入到办法体外部想进去时,个别有两种计划:单步调试缓缓进去,另一个就是 step out(举荐)

Drop frame:回到以后办法的 调用处,同时上下文内所有的变量的值也回到那个时候。该按钮可能点击的前提条件是:以后所处的办法有下级办法,如果你是 main 办法里,那么按钮就是灰色喽

Run to Cursor 运行到光标处:你想要代码在哪里停一下,就把光标放在哪就成。这个性能切实太好用了,大大缓解了稀稀拉拉的断点,强烈推荐

Evaluate Expression 表达式计算器:看图标就是个计算器嘛,所以你能够在这里执行 任何 非法的表达式

Trace Current Stream Chain 跟踪以后 Stream 流:只有代码停在 Stream 流语句上,此图标才点亮能够被点击。这是 IDEA 提供的因为调试 Stream 流的杀手锏级别的性能,放在文下具体解释

这一排按钮十分重要,甚至是最重要,肯定要熟练掌握,能够大大提高调试代码的效率,亲测无效。

服务按钮

把最右边一竖排定义为服务按钮,为调试过程提供服务。

一共 10 个,但都比较简单和好了解。同样的从上到下过一遍:

  1. Rerun xxx:敞开以后程序,从新运行
  2. Modify Run Configuration:顾名思义,批改运行的配置。点击此按钮的成果同点击右上角的框框:

点击会弹出这个配置窗口:

每份运行期配置都是具名且惟一的,相互隔离。运行配置可批改的项十分多,大略如下:

阐明:我截图的页面可能和你不一样,因为我用的是最新版的 IDEA,此页面在 2020.3 版本做了改版

  1. Resume Program:恢复程序。当断点激活时程序“进行”了,点击这个按钮就是复原的意思。它给到的成果是:跳到下一个断点 (用这句话解释貌似更容易了解些),若前面没有断点就间接运行完结了。这个按钮 十分罕用
  2. Pause Program:暂停程序。嗯,只有你当初“卡”在断点处,那么状态就是 Pause 的状态。这时候就有疑难了,难道这个按钮始终是灰色不可点状态?有啥用呢?我网络上看了看,简直 没人 可能解释它的作用,这里 A 哥尝试给你解释下,用张图给你整得明明白白,服服帖帖:

  1. Stop xxx:不解释
  2. View Breakpoints:关上断点治理窗口。文上已具体解释了此窗口的用法
  3. Mute Breakpoints:这个按钮挺有意思的,作用是让所有断点变为灰色,也就是说让它们 生效。它是一个批量操作,操作对象是所有断点,而不可针对于某一个。若你当初不想把所有断点删除,但又不想它们拦截你,那么可用这个按钮实现
  4. Get Thread Dump:拿到 以后线程 的 dump,能够查看到以后线程的状态。如下图:

  5. Settings:关上设置菜单。属于高级应用,每一项开启后有什么成果,放在文下解释

  1. Pin tab:如果你这会调试 xxx 这个程序很频繁,那么把它“钉”上会更有助于效率晋升

办法调用栈

显示 以后办法(位于栈顶)所通过的所有办法。

阐明:点击右上角的小漏斗图标能够不显示类库的办法,只显示你本人写的办法,不便调试

变量区 Variables

在此区域能够查看以后断点上下文范畴内的所有变量值(即便不在本类内也能够点过来查看哦),包含 static 动态的。

值得注意:此区域里的变量 IDEA 会主动调用其 toString() 办法,因而若你遇到失常运行只输入一句日志,debug 输入多句这种 case 很可能就是这个状况哦。

Watches 变量跟踪

有的时候变量很多,而只须要 重点关注 某几个变量,就能够应用 Watches。

除了以上这些,还有什么动静扭转变量值 set Value,跳转到源码处 jump to source 等都是十分实用的性能,这就留你本人开发和试验哈。

为何调试窗口没主动关上?

有同学遇到过这个状况:明明断点激活了(程序暂停了),然而那个“操作面板”并没有进去,怎么破?

话不多说,查看你的这个配置项是勾选状态即可。这个状态 IDEA 默认是勾选上的,个别不必操心。

断点调试的奇淫巧技

最初,站在应用层面,介绍些十分实用的“奇淫巧技”给你,这些小技巧可拿来就用。

强制返回(中断 debug)

场景形容:调试时,当我走到第三步就发现了问题,这个时候并不心愿走完后续流程(比方因为后面有 bug 后续流程会有删除数据操作等等),这个时候怎么解决?

咔嚓,Stop 程序。是的,很长一段时间里我也是这么干的,的确能达到目标。直到我发现了一个更优雅的办法:Force Return,成果为:强制返回办法返回值(本人给个值)来防止后续的流程。

条件断点

指定断点的激活条件,都能称作条件断点。个别状况下,在行断点下给定一个计算表达式,后果为 true 就激活断点这是最罕用的形式。因为下面已有案例,这里省略

多线程调试

多线程程序的益处诚然不必多说,但总所周知它调试起来是比拟艰难的,比方这段:

public static void main(String[] args) {
    // 共放 3 个 "令牌"
    CyclicBarrier cyclicBarrier = new CyclicBarrier(3);

    // 模仿多个线程去抢
    for (int i = 0; i < 10; i++) {new Thread(() -> {
            try {String name = Thread.currentThread().getName();

                System.out.println(name + ",筹备抢令牌");
                cyclicBarrier.await();
                System.out.println(name + ",已抢到");
            } catch (Exception e) {}}, "线程" + i).start();}

}

这个时候如果你想钻研 await() 办法的实现,须要具备的前提条件是多个线程进入,因而须要 hold 住 多个线程 。若只是在 await() 这一行打个一般的行断点,那后果是这样子的:

所有线程都是 Running 状态,显示这是不可能的,因为总共只有 3 个另外,拿完了其它的都得期待才对,所以这个基本就不是 实在的执行场景 ,也就不可能跟踪到 await() 办法外面去探索其实现。

为了模拟出这种场景进行调试,就对断点阻塞条件设置为这样:

再次运行程序,线程状况如下:

疾速计算表达式

都晓得调试面板里的 Evaluate Expression 能够计算表达式 / 变量的值,但那毕竟还得弹个窗稍显麻烦,其实还有更为不便的形式:

用鼠标操作,效率指数级晋升。这个操作形式是:鼠标指针选中表达式(IDEA 智能主动选中)+ 鼠标左键单击。当然喽,如果你想执行自定义的不存在于代码中的表达式,那必须调起窗口来操作。

Stream 流调试

Java 8 的风行,彻底让流式编程走进咱们的视线。应用 Stream 编程的益处泛滥,但始终被大家诟病的是难以浏览和 难以调试,特地是后者。

为了调试它,咱们常常须要插入其它断点,并剖析流中的每个转换,不可为不麻烦。还好 IDEA 提供了解决该痛点的“能力”:当调试器在 Stream API 调用链 之前或之内进行时,点击 Trace Current Stream Chain 这个图标即能够“十分难看”的图形化形式展现进去,高深莫测:

被动抛出异样

需要场景:你写了一个全局异样组件,当初想测试它失效状况如何,那么时候你就须要被动抛出这种异样,个别的做法是形如这样:

// 本人在程序内被动 throw 一个
throw new NullPointerException();

// 或者构建个表达式
int i = 1/0;

这种做法均有肯定的代码侵入性,用后还得删除。其实 IDEA 还提供了一种更为优雅的解决方案:


把握了 IDEA 断点调试的基本技能,上面进入到本文深水区:断点类型。难度不高,仍旧是应用层面的事,但因为很多同学并不知道,因而是你用于超车的好资料。

四大断点类型

对于打断点,预计大部分同学都只会右边鼠标单击这种最根底的形式。所以,看到这个小标题预计你得再懵一次吧。what?断点还有品种?

若你也是只在代码右边鼠标单击打上“小红点”,而后嘎嘎就是干,地面转体 720 度向后翻滚三周半 …… 一把唆的选手,那么接下来就坐稳喽,筹备发车。

这么个姿态兴许能帮你定位 50% 以上的问题,但还有另外一半的 case 呢?如 for 循环调试,Stream 流调试,lambda 调试、异样调试等这些场景,用那“一把唆 ”的形式就很难搞定甚至说搞不定了。断点是帮咱们 疾速定位 问题的,不同的场景打上适合的断点将能事倍功半。

殊不知,IDEA 给咱们开发者提供了十分的断点类型,以应答不同场景下的调试。在对应的场景下应用适合正确的断点类型,可能大大提高调试的效率,从而 他人加班你上班,效率就是工夫,而工夫就是生命。

如图,IDEA 把断点分为四大类型(截图中只有三类):

  1. Line breakpoint(行断点):图中红色小圆圈。顾名思义,在指定代码行设置断点
  2. Field watchpoint(属性断点):图中红色小眼睛。打在类的属性 (static or 非 static) 上的断点,作用是在该属性 读取和写入 时激活
  3. Method breakpoint(办法断点):图中红色小菱形。标记在办法签名的那一行,在该办法执行的入口 / 出口处被激活
  4. Exception breakpoint(异样断点):红色小闪电。这是一个非凡但很好用的断点,当程序抛出 指定异样 时会激活异样断点。和其它断点不同,异样断点是我的项目 全局的,它不须要打在具体某一行上

上面就到了“啃硬骨”的时候了,来吧。

行断点 Line breakpoint

应用得最最最宽泛的断点类型,平时大部分状况下都应用此种断点。

从“教程”中能够看到该断点有很多的设置项,也就是有很多的断点参数能够配置,来理解下。

断点参数

因为这是第一个介绍断点参数的类型,因而会说得具体些,这样子前面雷同性能的参数就不必再赘述了。对照这个截图页:

  • Enabled:不解释。但需注意:若此项不勾选上,小红点并不会隐没,而是由实心的变为 空心的,当然喽,个别状况下并不会动此项
  • Suspend:家喻户晓,断点激活时会阻塞程序的持续运行,从而阻塞以后线程。然而当你发现它是个复选框的时候,有没有被惊讶到?并且,并且,并且你还能够基本就不勾选它,有何区别:

    • 若不勾选选中:此断点相干流动(如打日志等)仍旧失常进行,只是 不阻塞过程
    • 若勾选中:

      • All(默认):阻塞该程序内所有线程
      • Thread:只阻塞 以后断点 所在线程

        如上图,不勾选 Suspend:线程 14 和线程 15 失常运行,“畅通无阻”

        如上图,勾选 Suspend-All:在断点处,所有线程 都被阻塞了,对立给我期待。

  如上图,勾选 Suspend-Thread:method1 的线程被阻塞,然而并不影响另外一个线程调用 method2。

试想一下,既然“勾选 Suspend-Thread”影响更小,那为何 IDEA 默认帮你抉择 All 而不是 Thread 呢?起因是这样子的:调试的目标就是让程序“慢下来”,最好是静止下来不便剖析问题。否则,其它线程如果仍旧持续放弃执行的话,可能一会这个申请改掉这个数据一会改掉那个数据,减少了不可控性。不确定的减少从而大大增加调试难度和定位问题的难度,所以索性上个“同步锁”来得省心,因而默认选中 Suspend-All 是正当为之。

阐明:很多时候咱们须要用本机连贯测试环境打断点进行近程调试,若在这个 case 下强烈建议你应用 Thread 模式,否则你懂的

  • Condition:断点被激活的条件。你能够在此处书写表达式,只有表达式返回 true 时此断点才会被激活

    • 条件断点严格来讲不属于一种断点类型,属于断点参数决定的,很多类型的断点都可加条件

  • Log:它有三个选项,是 checkbox 哦。也就是说可都选,也可都不选,默认一个都不选

    • Breakpoint hit message:断点激活时输入提醒日志
    • Stack trace:断点激活时输入程序调用栈信息
    • Evaluate and log:抉择须要输入计算表达式的值。你可抉择以后可达的变量,如本例的 main 函数入参 args 等
  • remove once hit:断点激活一次后就立马给移除喽,也就是所谓的长期行断点,上面来介绍下它

还有窗口里最左边的这块条件:

见名之意,一系列过滤器:过滤实例、过滤类、过滤调用者等等,个别这些们简直不会应用(至多我目前是还没用过的),所以就一笔带过。

应用场景

行断点个别配合单步调试一起应用,在看框架源码、定位根底问题等应用得特地多,是最须要把握的一种断点类型,没得磋商。

长期行断点 Temporary line breakpoint

它也属于行断点的一种,只是参数不一样而已。因为它比拟非凡,所以单摘出来说道说道。创立一般行断点,而后把 Remove once hit 复选框勾选上即是一个长期行断点,成果如下:

这种断点类型,理论应用场景其实很少。

属性断点 Field watchpoint

此类断点是打在属性上的,成员属性和动态属性均可。它不是小红点,而是个红色“小眼睛”。

断点参数

如图,此种断点类型 特有 个 watch 参数,两个可选值的含意为:

  • Filed Access:读取此属性时(写入时不论)
  • Filed madification:写入此属性时(读取时不论)

应用场景

当想晓得 xxx 属性的赋值是谁时,因为程序太庞杂没法晓得断点打哪儿从哪开始跟踪,这个时候应用属性类型的断点一下子就搞定了,十分的不便。

办法断点 Method breakpoint

断点必须打在办法签名的那一行,色彩形态是个红色的小菱形。

断点参数

Watch 有三个可选值:

  • Emulated:仿真。作用:进步调试性能,因而默认状况下应用。官网倡议:仅在调试近程代码或在没有行号信息的 native 办法或 类中 设置断点时,才倡议禁用此选项
  • Method entry:进入办法时激活断点
  • Method exit:进来办法时激活断点

若 entry 和 exit 都勾选,那在进入之后和进来之前都会激活断点

应用场景

对于此种断点类型,可能你会说没啥卵用。毕竟本人在办法头尾打个行断点就能达到同样成果,没必要独自搞个类型嘛。

其实,它的 杀手锏级 应用场景是把此种类型断点打在 接口办法 上,这样子不论哪个实现类办法被调用,都会激活断点,是不是特地给力。

异样断点 Exception breakpoint

比拟小众,但并不代表不重要。在我了解它比拟小众,可能大多数同学不晓得如何打一个异样断点,因为它不是鼠标单击就能轻松搞定。

下面介绍了异样断点它是一种 全局断点类型,因而并不能在代码处间接单击,而是只能在治理窗口里对立增加:

和其它断点类型相比,至多有如下不一样:

  1. 创立断点只能通过断点治理窗口创立,而不能通过鼠标点击形式
  2. 创立实现后,代码栏处不会有任何显示(没有红色小图标),直到它被激活时才会呈现红色小闪电
  3. 异样断点作用于全局:本例中任何中央抛出了 NullPointException 都会激活此断点

断点参数

Notification 有两个可选值:

  • Catch excetion:只有当你本人 try-catch 了这个异样才会激活断点
  • Uncatch excetion:只有当你本人不 try-catch 时才会激活断点

默认状况下这两个都会被勾选上,也就是说任何状况下产生此异样,都会激活断点。

应用场景

通晓了异样断点的作用和触发条件,应用场景就有啦。比方当你的程序抛出了一个异样,然而一时半会你并不知道是哪行代码引起的,这个时候通过减少异样断点的形式能够实现 迅速的 问题定位。

4 种断点图标比照

每种断点类型都有本人对应的图标,且有不同的状态。我从官网趴了一张比照图,总结得特地好,在这里一并分享给你:

近程调试(近程 Debug)

当初大都是微服务架构形式,每个微服务个别会有 N 多个上 / 上游依赖,如此以至于给调试带来了很大艰难,毕竟你简直不可能在本地同时把依赖都启起来用 IDEA 做调试。所以,近程调试来了,它是调试分布式系统的一个利器。

近程调试:顾名思义,应用本地 IDEA 调试近程代码(个别为 QA 环境,线上环境不可能开启调试端口的)。那么如何开启近程调试呢?

开启步骤

开启近程调试只须要两步即可:

第一步:让近程部署的那个利用反对近程调试,也就是裸露近程调试端口。形式办法为在利用启动时加上对应的 JVM 参数即可,JDK 版本不同参数也不一样

  • JDK 9+:-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:${debug_port}
  • JDK 5-8:-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=${debug_port}
  • JDK 4:-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=${debug_port}
  • JDK 3-:-Xnoagent -Djava.compiler=NONE -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=${debug_port}

第二步:用 IDEA 创立一个 remote 运行配置,填上近程主机的 ip + 裸露的调试端口即可。操作门路为:Edit Configurations -> Add New Configuration ->

万事俱备,点击 debug 运行,控制台里能看到如下字样就证实你链接胜利了:

值得注意的是:近程调试时请确保你本地代码和近程代码 截然不同,以达到最佳成果。

传统 Tomcat 如何开启近程调试?

若你是个 Spring Boot 利用,那么在 jar -jar 时加上 JVM 参数即可,那么如果是要应用传统的 tomcat 形式部署呢?这个时候找到传统 tomcat 的启动脚本startup.sh

#!/bin/sh
os400=false

...

PRGDIR=`dirname "$PRG"`
EXECUTABLE=catalina.sh

...

exec "$PRGDIR"/"$EXECUTABLE" start "$@"

为了加上咱们的 JVM 参数,只须要在 exec xxx 之前增加一个变量值即可(以 JDK8 为例):

JPDA_OPTS='-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address= 具体的端口号’

留神:这个 key 名称必须是 JPDA_OPTS。

有好奇心的你可能不禁就要问了:为何加个 JPDA_OPTS 参数就行了呢?也没见 exec xxx 应用它呀,其实不然,上面简略解释下,不开展。

exec执行时援用了变量 $EXECUTABLE,它代表的是就是 catalina.sh 这个文件,该文件外面有大量变量判断脚本,当然包含负责对 JPDA_OPTS 解释:

#!/bin/sh

cygwin=false
darwin=false
...
if ["$1" = "jpda"] ; then
  if [-z "$JPDA_TRANSPORT"]; then
    JPDA_TRANSPORT="dt_socket"
  fi
  if [-z "$JPDA_ADDRESS"]; then
    JPDA_ADDRESS="localhost:8000"
  fi
  if [-z "$JPDA_SUSPEND"]; then
    JPDA_SUSPEND="n"
  fi
  if [-z "$JPDA_OPTS"]; then
    JPDA_OPTS="-agentlib:jdwp=transport=$JPDA_TRANSPORT,address=$JPDA_ADDRESS,server=y,suspend=$JPDA_SUSPEND"
  fi
  CATALINA_OPTS="$JPDA_OPTS $CATALINA_OPTS"
  shift
fi
...

对于 JVM 调试平台 JPDA 更多知识点,可自行用谷歌百度一下学习学习

嵌入式 Tomcat 如何开启近程调试?

这不就是 Spring Boot 利用模式麽?所以,如何开启,不必再废话了吧~

总结

人和动物的最大区别之一是人会应用工具,且长于应用工具。工具被发明进去,使命就是提效的,毕竟咱们不可能用记事本去写 Java 程序吧。

IntelliJ IDEA 作为最为风行的 JVM 平台 IDE,咱们应该尽可能的去挖掘出它的效用,既然作为集成开发环境,其实很多性能都能够一站式搞定,在一个平台里做很多数据都能买通。比方 IDEA 的 rest 接口调试、数据库映射、Shell 终端等等,应酬平时的开发个别搓搓无余,举荐应用,毕竟软件启得越多电脑越卡不是。

用 IDEA 和会用 IDEA 是两个档次,除了代码自身,最罕用的开发工具也是值得花番心理的。大道至简,知易行难,知行合一,失去功成!

本文思考题

本文所属专栏:IDEA,后盾回复专栏名即可获取全部内容,已被 https://www.yourbatman.cn 收录。

看完了不肯定懂,看懂了不肯定会。来,文末 3 个思考题帮你复盘:

  1. 断点能打在类上吗?
  2. IDEA 能设置哪几种类型的断点呢?各有什么场景?
  3. 如何用 IDEA debug 调试测试环境的利用?

举荐浏览

  • 玩转 IDEA 我的项目构造 Project Structure,打 Jar 包、模块 / 依赖治理全搞定
  • 谁再把 IDEA 的 Project 比作 Eclipse 的 Workspace,我就跟谁急
  • IntelliJ IDEA 20 周岁啦,为期 2 天的周年庆流动对开发者收费凋谢
  • IntelliJ IDEA 2020.3 正式公布,年度最初一个版本很讲武德

System.out.println("点个赞吧!");
print_r('关注【BAT 的乌托邦】!');
var_dump('私聊 A 哥:fsx1056342982');
console.log("点个赞吧!");
NSLog(@"关注【BAT 的乌托邦】!");
print("私聊 A 哥:fsx1056342982");
echo("点个赞吧!");
cout << "关注【BAT 的乌托邦】!" << endl;
printf("私聊 A 哥:fsx1056342982");
Console.WriteLine("点个赞吧!");
fmt.Println("关注【BAT 的乌托邦】!");
Response.Write("私聊 A 哥:fsx1056342982");
alert("点个赞吧!");

A 哥 (YourBatman):Spring Framework 开源贡献者,Java 架构师,领域专家。文章不题目党,不哗众取宠,每篇文章都成系列去 零碎的 攻破一个知识点,每个系列可能是 全网最佳 / 惟一。重视基本功涵养,底层根底决定上层建筑。现有 IDEA 系列、Spring N 多系列、Bean Validation 系列、日期工夫系列 …… 关注收费获取

正文完
 0