首页 > 其他分享 >为什么方法断点那么慢

为什么方法断点那么慢

时间:2022-10-21 12:22:21浏览次数:70  
标签:为什么 end debugger 方法 VM 断点 method

原文
一些IDE提供“方法断点”的功能,可以让断点调试看起来非常简洁,然而在调试过程中我们会发现调试反应时间很长,调试器的性能大大降低。在本文中,我会简单解释方法断点的实现原理,以及为何导致性能变差的原因。

为了更好的理解,我先简单说明一下断点是如何实现的,以及调试器的工作原理。

JPDA(Java Platform Debugger Architecture)

JPDA是JAVA调试框架,主要用于debugger(调试器)和debuggee(调试程序或进程)之间的通信。JPDA主要由三个主要API构成。

  1. JVM TI(JVM Tool Interface) : 一个native接口,定义了VM提供debug的函数。
  2. Java Debug Wire Protocol(JDWP):JDWP是一个定义debugger和debuggee通信的Api。
  3. Java Debug Interface(JDI): Java接口,用于前端和后端的通信交互,JDI内部实现了JDWP接口。
  4. 下图和文章中的前后端(back-end and font-end)分别指的是运行在VM上的调试程序(进程)和编辑器。
  5. 调试链:相关事件发生时(比如打断点,单步调试,调试时修改参数值),VM通过回调(JNI: java Native Interface,VM通过JNI来调用Native Interface)调用JVM TI,然后back-end发送event给font-end。debugger通过JDI和JDWP与后端通信。

为何要用方法断点

如果调用的方法无法访问源码,或者方法内有多个if出口,此时用方法断点很简洁。

JAVA断点原理

在编辑器打一个断点,往往内部会进行三步

  1. 允许断点事件:VM允许debugger激活各种事件。font-end调用 SetEventNotificationMode() 方法启用 can_generate_breakpoint_events ,当运行到断点处,VM会触发事件通过debugger链返回值。
  2. 注册断点:通过 SetBreakpoint 方法设置断点,当线程运行到断点处,VM会将所有active线程暂停,并且触发断点事件。
    SetBreakpoint(jvmtiEnv* env,
    
                  jmethodID method, //注意一下此变量,下文会再次提到。
    
                  jlocation location)
    
  3. 断点事件:VM触发的事件叫断点事件,用于通知debugger。事件: Breakpoint(xxx)

方法断点

实际上JDPA不提供方法断点的功能,方法断点是编辑器提供的。

debugger调用上文说的 SetEventNotificationMode()
启用 can_generate_method_entry_eventscan_generate_method_exit_events,当VM运行进入和退出方法时,会向debugger发送 方法进入退出事件:

MethodEntry(....,JmethodID method)
MethodExit(....,JmethodID method)

断点实现流程:

  1. IDE将断点添加到编辑器内置维护的一个断点list里。
  2. debugger调用上文说的SetEventNotificationMode(),启用entry method和exit method,当VM运行代码进入和退出方法时,会向debugger发送事件。
  3. 每当进入和退出方法时,VM会向font-end发送MethodEntry或MethodExit。
  4. IDE根据事件中的jmethodID,来检索该id是否存在于断点list中。
  5. 如果存在,debugger则调用 SetBreakPoint 方法,将请求发送到VM。
  6. VM运行代码到断点处,停止活动线程,并且将event返回debugger

和普通断点的区别在于:方法断点在流程中需要先判断该方法是否被前端标记为应该要打上断点,然后才是注册断点。

调试方法断点为何很慢

  1. JmethodID:JmethodID是正在运行方法的标识符。每次VM需要返回MethodEntry和MethodExit时都需要携带JmethodID,然而VM查找获取JmethodID需要较长时间。
  2. communication:methodEntry和MethodExit导致前端和后端之间进行大量的通信往返。
  3. VM callback is synchronization:VM触发事件使用回调时,经过以下几个步骤(都是同步操作):
    1. 将context切换到back-end,back-end通知font-end
    2. font-end根据返回的jmethodID,查找是否存在于断点list中。
      在此期间代码执行是暂停的。

总结

  1. 尽量减少方法断点的使用。
  2. 如果不必要,可以只使用methodEntry,不激活methodExit,减少查找以及通信次数。

标签:为什么,end,debugger,方法,VM,断点,method
From: https://www.cnblogs.com/allworldg/p/why-method-breakpoint-slow.html

相关文章

  • PHP保留两位小数的几种方法
    这篇文章主要介绍了PHP保留两位小数的几种方法,需要的朋友可以参考下 代码如下所示:$num=10.4567;//第一种:利用round()对浮点数进行四舍五入echoround($num,2......
  • 为什么要反对精致的利己主义者
    1.眼里揉不进沙子早上和同学探讨一个问题眼里揉不进沙子是一个褒义词还是贬义词而我们最后得出的结论是,它是中性的。为什么呢?因为这个要看在什么情况去使用。如果一个......
  • springboot项目引入自己开发的jar包的处理方法
    在开发过程中自己创建了一个jar包,调试没有问题,但是build的时候提示找不到jar包。这是因为在maven仓库中找不到自定义的jar包。解决办法:一种是将jar包安装到本地maven仓......
  • 【Jmeter】-调用JAR包方法中文乱码
    前言最近有个项目开发给了JAR包要做签名,可是Jmeter调用签名方法中文乱码。上网一顿查找,只能找到请求和响应中文乱码问题的解决方法,然却不能解决我的乱码问题(ಥ﹏ಥ)(ಥ﹏ಥ)(......
  • 【sysbench】read_write测试方法与脚本
    测试工具Sysbench是一个基于LuaJIT的可编写脚本的多线程基准测试工具。它最常用于数据库基准测试,但也可用于创建不涉及数据库服务器的任意复杂工作负载,本次测试将采用Sys......
  • [转]Mysql字符集和字符序及修改方法
    原文地址:RDSMySQL字符集相关说明(aliyun.com)总结:有表情或者特殊字符,字符集使用utf8mb4;需要区分大小写,字符序使用_bin等,_ci不区分大小写概述本文主要介绍RDSM......
  • 为什么回家抢个票这么难:原来你忽略了这十个技巧!
    这是 herongwei 的第 96 篇原创阅读本文大概需要3 分钟。2019年就要结束了,看一下日历,还有2天就是2020年的元旦了。时间过得真的快。2019年,你看着自己支付宝里所......
  • 我为什么会从Google辞职?
    今天分享一名前谷歌工程师,下定决定从谷歌离职,离开目前这个安稳的环境,去做一些新探索的心里路程。每当我身边的朋友听到我从Google辞职的消息,都会不约而同地问我:“那么,接下......
  • 设计模式—关于提高可扩展性(方法层面)的学习(更加从容的应对需求变更)
    上一节主要学习了提高复用性的几种设计模式,本节学习方法的可扩展性以及怎么更好的扩展方法。方法是组成程序的基础单元,基础单元的可扩展性是整个程序的可扩展性保障,可扩展......
  • ttf是什么文件格式?ttf文件怎么打开方法
    http://g.pconline.com.cn/x/895/8956417.html.ttf文件是字体文件,当电脑里有时自带的字体文件不能满足我们编辑的需要,这时就要我们下载一些字体文件,随着windows的流行,已经......