使用 JVMTI 测量 Java 的执行时间
对于我使用 JVMTI 实现的探查器想要开始测量所有 Java 方法的执行时间。 JVMTI 提供事件:
MethodEntry
MethodExit
所以这很容易实现,但是我遇到了这个 注释:
启用方法进入或退出事件会显着降低许多平台上的性能,因此不建议用于性能关键用途(例如分析)。在这些情况下应使用字节码检测。
但我的分析代理是无头工作的,这意味着收集的数据被序列化并通过套接字发送到显示结果的服务器应用程序。我应该如何使用字节码检测来实现这一点。我有点困惑如何从这里继续下去。有人可以向我解释一下,如果我必须改变策略,或者我该如何解决这个问题?
For the profiler which I implement using JVMTI I would like to start measuring the execution time of all Java methods. The JVMTI offers the events:
MethodEntry
MethodExit
So this would be quite easy to implement, however I came across this note in the API:
Enabling method entry or exit events will significantly degrade performance on many platforms and is thus not advised for performance critical usage (such as profiling). Bytecode instrumentation should be used in these cases.
But my profiling agent works headless, which means the collected data is serialized and sent via socket to a server application displaying the results. How should I realize this using byte code instrumentation. I am kind of confused how to go on from here. Could someone explain to me, if I have to switch the strategy or how can I approach this problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我不了解 Sun JVM,但当您请求 MethodEntry/Exit 事件时,IBM JVM 会进入我们所说的 FullSpeedDebug 模式......FSD 会大大减慢执行速度。
正如您所说,您可以像我的分析器一样使用 BCI,但除非您对检测的方法有选择性,否则您也会看到速度变慢。例如,我的探查器在每个条目上插入一个 if(profiling) callProfilerHook(),并且在所有对象创建的方法以及其他一些区域中的所有可能的出口处插入......这些额外的检查可能会使执行速度减慢 50% 以上。 ..
至于如何BCI...我编写了自己的C库来做到这一点...技术上并不难(提示只需删除StackMapTable),但我可能需要你一段时间..或者你可以使用ASM等。等人。
最后... callBackHook 会增加开销,并且在小方法上会导致报告的 CPU/时钟时间毫无意义,除非您执行一些复杂的开销计算...即使您这样做,您的回调代码也会影响处理器 L1 缓存和 Java 的形状代码变得效率较低,因为它的空间较小。
我的探查器基本上忽略了报告的时间,因为我以一种有趣的方式可视化执行情况...我希望了解所有代码的流程,事实上在大多数情况下代码正在运行(大多数 Java 项目不知道有数百万在他们的应用程序中运行的第三方代码行)
I don't know about the Sun JVM but the IBM JVM goes into what we call FullSpeedDebug mode when you request the MethodEntry/Exit events.... FSD slows down execution quite a bit.
As you say you can use BCI as my profiler does but unless you are selective about which methods you instrument you will also see a slow down. For example my profiler inserts a if(profiling) callProfilerHook() on every entry and all of the possible exits in a method all object creates and some other areas as well.... These additional checks can slow down execution by over 50%...
As for how to BCI... well I wrote my own C library to do it... it's technically not hard (hint just delete the StackMapTable) but I may take you a while.. Alternatively you can use ASM et. al.
Finally... you callBackHook will add overhead and on small methods render the reported CPU/Clock time meaningless unless you perform some sophisticated overhead calculation... even if you do this your callback code affects the shape of the processor L1 caches and the Java code becomes less efficient because it has less room..
My profiler basically ignores the reported times as I visualize the execution in an interesting way... I'm looking to understand the flow of all of the code, in fact in most cases what code is running (most Java projects have no idea of the millions on lines of third-party code running in their app)