问题标签 [jvmti]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
18248 浏览

java - AttachNotSupportedException 由于 Attach API 中缺少 java_pid 文件

构建我自己的分析器,我使用JVMTI API 来构建本机库代理。通过使用附加参数 -agentlib 可以与 JVM 一起启动此代理。此外还有Attach API,它允许将代理注入到正在运行的 JVM 中。我想使用以下代码在我的分析器中实现此功能:

它有什么作用?从所有可用的正在运行的虚拟机 ( VirtualMachine.list()) 中,我选择第一个,附加到它并尝试将我的代理加载到其中。可以找到名为 libagent.so 的 UNIX 系统上的代理,但在尝试加载代理时会引发以下异常:

查看源代码,抛出此异常,因为它找不到名为.java_pid<pid>. 我在文档中没有找到很多关于这种文件的信息。我经常听说这种文件不再使用了,但我正在运行 Java 1.6。

我还尝试附加到其他 JVM,实际上我保持这个附加过程是动态的,出于测试原因,我只是尝试附加到任何 JVM。


这是导致异常的代码,取自sun.tools.attach: LinuxVirtualMachine.java

它说,它正在从根/proc/<pid>目录中查找。查看 JDK7 的变更集,他们似乎正在将代码JDK7 变更集更改为 LinuxVirtualMachine

0 投票
2 回答
355 浏览

java - notifyAll() 分析时的调用次数差异

我已经使用 JVMTI 实现了一个简单的分析器来显示在wait()和上的调用notifyAll()。作为测试用例,我正在使用。Oracle 的生产者消费者示例。我有以下三个事件:

  • notifyAll() 被调用
  • wait() 被调用
  • 等待()离开

wait()调用及其离开时使用事件MonitorEnterMonitorExit. 退出具有名称的notifyAll()方法时会分析调用。notifyAll

现在我有以下结果,第一个来自分析器本身,第二个来自 Java,我在其中放置了适当的System.out.println语句。

有人解释这种差异的来源吗?notifyAll()被调用了这么多次。有人告诉我这可能是由于 Java 对操作系统的请求的误报响应造成的。

它向操作系统发送了一个notifyAll()请求并发送了一个误报响应,看起来请求成功了。由于notifyAll是通过分析方法调用而不是MonitorEnter它来记录的,因此可以解释为什么等待不会发生这种情况。

我忘了说,我没有单独运行程序,两个日志都来自同一个执行。

附加信息

最初作为答案添加,由 extraneon 移至问题:

我想我发现了一些额外的 notifyAll 来自哪里,我添加了调用 notifyAll 的方法上下文的分析:

但是即使没有这些外部调用,也有很多 notifyAll 调用不会出现在 printf 调试中。

0 投票
1 回答
1633 浏览

java - 使用 JVMTI 测量 Java 的执行时间

对于我使用JVMTI实现的分析器,我想开始测量所有 Java 方法的执行时间。JVMTI 提供以下事件:

  • MethodEntry
  • MethodExit

所以这很容易实现,但是我在 API 中遇到了这个注释:

启用方法进入或退出事件将显着降低许多平台上的性能,因此不建议将其用于性能关键用途(例如分析)。在这些情况下应该使用字节码检测。

但是我的分析代理无头工作,这意味着收集的数据被序列化并通过套接字发送到显示结果的服务器应用程序。我应该如何使用字节码检测来实现这一点。我有点困惑如何从这里继续。有人可以向我解释一下,如果我必须改变策略或者我该如何解决这个问题?

0 投票
2 回答
2390 浏览

java - 在运行时卸载 JVMTI 代理?

我正在使用附加 API 在运行时加载 JVMTI 代理。我想在我的程序完成后卸载 JVMTI 代理,而不终止加载代理的 JVM。根据此文档,无法从附加 API 执行此操作。是否有任何其他方法可以强制代理通过 Java API 或从 JVMTI 代理中卸载自身?

0 投票
1 回答
2045 浏览

java - 使用 JVMTI 获取 GC 释放的内存量

我正在尝试使用 JVMTI 来了解 GC 释放了多少内存,这将用作分析器的一部分。

使用 JVMTI 我可以获得 GC_START 和 GC_END 的事件。JVMTI 还提供了遍历堆的设施,从中我可以得到它的确切当前大小。逻辑上我可以得到 GC_START 和 GC_END 的堆大小,然后得到堆大小的差异。

问题是,虽然 GC_START 和 GC_END 事件处理函数的大部分 JVMTI 功能被禁用,我得到一个 JVMTI_ERROR_UNATTACHED_THREAD (115) 错误。

如果我查看 JVMTI API 参考 http://download.oracle.com/javase/6/docs/platform/jvmti/jvmti.html#GarbageCollectionStart

“Garbage Collection Start 此事件在 VM 仍然停止时发送,因此事件处理程序不得使用 JNI 函数,并且不得使用 JVM TI 函数,除非那些特别允许此类使用的函数(请参阅原始监视器、内存管理和本地环境)存储功能)。”</p>

所以看来我无法从事件处理程序访问内存。

GetCurrentHeapMemory 函数中引发错误。

代码如下 /* * memory_collector.c * * 创建于:2011 年 5 月 8 日 * 作者:ycarel */

我很高兴获得有关如何使用 JVMTI 收集此信息的信息,也将不胜感激 JVMTI 的替代品。

谢谢

0 投票
1 回答
378 浏览

java - 使用 JVMTI 进行死锁检测

我想知道是否可以使用 JVMTI 在 Java 中动态检测死锁。有两个事件使用 synchronized 语句指示监视器上的操作:

监控竞争进入

当一个线程试图进入一个已经被另一个线程获取的 Java 编程语言监视器时发送。

监视器竞争进入

当一个线程在等待另一个线程释放它后进入 Java 编程语言监视器时发送。

这意味着,使用 JVMTI 我只能看到那些已经被锁定的监视器。我想重建一个等待图,但没有事件告诉我,获取了一个被任何线程持有的锁。这是不可能的。

有替代品吗?Unix 上的 SIGQUIT 命令允许显示死锁的线程转储,这在 JVMTI 中似乎是不可能的。

0 投票
1 回答
599 浏览

java - 使用 JVMTI 测量方法执行

使用 JVMTI 提供的MethodEntryMethodExit事件挂钩,我将如何测量在 Java 中执行的方法的时间?

简单来说就是:time2 - time1但是我看到的问题,如何区分不同的方法?有一个methodID,但是递归调用呢?方法打开后什么时候关闭?

我应该比较堆栈跟踪吗?什么是有意义的数据结构来跟踪输入的方法?就像是Map<StackTrace,Time>?

0 投票
3 回答
2944 浏览

java - 分析与检测 - Java

基本问题:JVM 提供了 JVMTI 用于分析和调试 JVM 的原生 API。JVM 检测也做同样的事情(对吗?)。如果是,两者有什么区别?

0 投票
1 回答
409 浏览

windows - 编译代理没有错误和“无效的 Windows 映像”的消息

自从一周以来,我正在尝试编译 JVMTI 演示集的演示版本。在这种情况下,我尝试编译 HeapViewer 源代码(我只是将文件 HeapViewer.c 重命名为 HeapViewerByMG)。我尝试了不同的编译器,并主要使用了我在 stackOverflow 上找到的以下代码:

我的代码在这两种情况下都编译成功,但是当我尝试使用 dll 文件时,我会收到以下错误:

“应用程序或 DLL (...)\heapViewerByMG.dll 不是有效的 Windows 映像。请对照您的安装软盘检查。”

我还查了这条消息的含义。研究告诉我,这是一个损坏的文件,但我可以排除这种情况,因为我通过 JVM 编译了给定的源代码。无论如何,我相信这只是我需要让文件成功运行的另一个选项命令。你们中有人有想法吗?

以下是我的系统的一些详细信息:

或者在我将 Microsoft 编译器从 64 位更改为 32 位之后(因为这是我启动代理时较旧的错误消息之一)

我在 Intel(R) 4 CPU 2.80GHz 和 2.00 GB RAM 上运行 Microsoft Windows XP Professional Version 2002 Service Pack 3

对不起那个系统。通常我使用的是 MacBook Pro 2010(2.8GHz Intel Core i7),但我发现 MacOS 不包含对 JVMTI 演示版的支持 :(

我希望有人能帮助我。

问候马库斯 G。

0 投票
3 回答
605 浏览

java - 使用 JVMTI 的线程感知堆分配跟踪

编写分析我还将实现堆分析的典型任务。具体我想跟踪一下,哪个线程分配了多少数据?使用 JVMTI,我认为挂钩事件VM Object AllocationObject Free就足够了。可悲的是,我读到第一个事件没有被触发,因为调用new.

我的最后一个想法是检查事件MethodExit的名称是否为<init>,从而将此调用声明为对象分配。但是,在此事件中,我无法获取对象,因此无法调用GetObjectSize.

简单地遍历堆,不包含关于哪个对象由哪个线程分配的信息。有谁知道如何实现这个?