Java JVMTI无法与-Xdebug -Xrunjdwp一起使用

13

我花了最近4个小时试图在远程运行的Tomcat实例上设置Eclipse TPTP内存分析,但一直未能成功。 根据TPTP和代理控制器文档,这应该是可行的。

我按照网站上的说明,在我的Eclipse(Galileo)工作台上安装了TPTP组件(4.6.0),并安装了代理控制器。为了启用代理,我添加了以下选项到启动Tomcat实例的命令行:

-agentlib:JPIBootLoader=JPIAgent:server=enabled;HeapProf:allocsites=true

并将以下目录添加到PATH的前面:

D:\dev\tools\ac\plugins\org.eclipse.tptp.javaprofiler
D:\dev\tools\ac\bin

尝试启动Tomcat时,我始终收到以下错误消息:

ERROR: JDWP unable to get necessary JVMTI capabilities. ["debugInit.c",L279]

我进行了大量的谷歌搜索,但没有找到任何相关的信息;我尝试重新安装TPTP和各种版本的代理控制器。

最后问题的原因是我使用了"jpda"选项启动Tomcat,这个选项在catalina.bat中被翻译成了......

-Xdebug -Xrunjdwp:transport=.....

去除"jpda"命令参数后,JVMTI开始工作。

所以,问题是:我在搜索期间没有找到任何信息表明JVMTI agent与调试不兼容。能否有人解释一下发生了什么,为什么JVMTI + JDWP不是一个有效的设置?

3个回答

21

到目前为止,所有的答案都不正确。如果查询所提到的错误,这是谷歌上出现的第一个结果。因此,我觉得需要一些澄清。

JVMTI和JDWP确实可以一起使用,事实上它们通常必须一起使用。如果在命令行中多次指定-Xrunjdwp(和/或可能的-agentlib:jdwp),则会出现ERROR: JDWP unable to get necessary JVMTI capabilities的错误。要修复这个问题,请确保在命令行中只有一个-Xrunjdwp-agentlib:jdwp

了解更多详情,请继续阅读...

JVMTI(Java虚拟机工具接口)是JVMDI(Java虚拟机调试接口)和JVMPI(Java虚拟机分析接口)的后继者。它包含了JVMDI和JVMPI的功能,这两个接口在Java 5中被弃用并在Java 6中被移除。它是暴露JVM内部以进行调试和分析的API。

JDWP(Java调试线协议)是一种协议,描述了一种简单的传输命令和响应的机制。据我所知,它是位于JVM外部的调试器与JVM通信并与JVMTI交互的唯一方式。

JDI(Java调试器接口)是一个客户端(调试器端)API,它在更多或更少透明地使用JDWP的同时暴露了JVMTI的某些功能。

Bob Dobbs提到的bug指的是误导性的错误消息,以及JVM会尝试为每次在命令行上指定它时加载JDWP。它并没有说明JDWP和JVMTI不能一起使用。

更多信息请参见: https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_74/rzaha/jpdebuga.htm


那么,是否可以同时使用远程调试和性能分析? - michael nesterenko
1
@michael 我认为是这样,但是除非你试图模仿某些奇怪的条件以尝试复制内存泄漏或巨大的CPU峰值,否则在调试时进行分析不是一个好主意吗? - Codebling
非常好的答案。我一直遇到这个错误。在我能够让YourKit分析器配置与它一起工作之前,我必须在我的古老Sun应用服务器上禁用调试模式。谢谢! - jlpp
1
@michaelnesterenko 实际上答案是“这取决于”。它取决于性能分析代理机从jvmti请求的能力。例如,断点能力可能仅由一个环境拥有(并且每个代理机都有自己的环境);https://docs.oracle.com/javase/7/docs/platform/jvmti/jvmti.html#capability。因此,如果分析器代理机需要设置断点的能力,您的调试器代理机将无法获得它们(或反之亦然)。这意味着每当您遇到此类错误时,您无能为力,您将无法在这些情况下进行调试。 - Haasip Satang
除非您至少同时使用-agentpath=jdvmi.so-Xrunjdwp:transport…,否则无法分配JVMTI代理和启用远程调试接口。没有办法仅指定jdvmi代理和jwp传输选项,而不使用两者。 - gabriel
@gabriel 等一下,你想做什么?这是一个非常老的答案。 - Codebling

3

我遇到了和你一样的问题,但是我找到了一个JVM的bug报告(http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6354345),它为这个问题提供了一些线索。基本上,问题在于Java代理库从未被设计成在同一个虚拟机中加载两次。很遗憾,但似乎这是代理系统的基本限制,你不能同时做这两件事。


1
对我来说,这与Code Bling的帖子中的问题相同,它们是重复的-Xrunjdwp,我没有意识到还有第二个-Xrunjdwp,因为它隐藏在变量%JAVA_OPTIONS%中,请检查您的应用服务器启动脚本。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接