问题标签 [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.
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
java - notifyAll() 分析时的调用次数差异
我已经使用 JVMTI 实现了一个简单的分析器来显示在wait()
和上的调用notifyAll()
。作为测试用例,我正在使用。Oracle 的生产者消费者示例。我有以下三个事件:
- notifyAll() 被调用
- wait() 被调用
- 等待()离开
wait()
调用及其离开时使用事件MonitorEnter
和MonitorExit
. 退出具有名称的notifyAll()
方法时会分析调用。notifyAll
现在我有以下结果,第一个来自分析器本身,第二个来自 Java,我在其中放置了适当的System.out.println
语句。
有人解释这种差异的来源吗?notifyAll()
被调用了这么多次。有人告诉我这可能是由于 Java 对操作系统的请求的误报响应造成的。
它向操作系统发送了一个notifyAll()
请求并发送了一个误报响应,看起来请求成功了。由于notifyAll
是通过分析方法调用而不是MonitorEnter
它来记录的,因此可以解释为什么等待不会发生这种情况。
我忘了说,我没有单独运行程序,两个日志都来自同一个执行。
附加信息
最初作为答案添加,由 extraneon 移至问题:
我想我发现了一些额外的 notifyAll 来自哪里,我添加了调用 notifyAll 的方法上下文的分析:
但是即使没有这些外部调用,也有很多 notifyAll 调用不会出现在 printf 调试中。
java - 在运行时卸载 JVMTI 代理?
我正在使用附加 API 在运行时加载 JVMTI 代理。我想在我的程序完成后卸载 JVMTI 代理,而不终止加载代理的 JVM。根据此文档,无法从附加 API 执行此操作。是否有任何其他方法可以强制代理通过 Java API 或从 JVMTI 代理中卸载自身?
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 的替代品。
谢谢
java - 使用 JVMTI 进行死锁检测
我想知道是否可以使用 JVMTI 在 Java 中动态检测死锁。有两个事件使用 synchronized 语句指示监视器上的操作:
监控竞争进入
当一个线程试图进入一个已经被另一个线程获取的 Java 编程语言监视器时发送。
监视器竞争进入
当一个线程在等待另一个线程释放它后进入 Java 编程语言监视器时发送。
这意味着,使用 JVMTI 我只能看到那些已经被锁定的监视器。我想重建一个等待图,但没有事件告诉我,获取了一个不被任何线程持有的锁。这是不可能的。
有替代品吗?Unix 上的 SIGQUIT 命令允许显示死锁的线程转储,这在 JVMTI 中似乎是不可能的。
java - 使用 JVMTI 测量方法执行
使用 JVMTI 提供的MethodEntry
和MethodExit
事件挂钩,我将如何测量在 Java 中执行的方法的时间?
简单来说就是:time2 - time1
但是我看到的问题,如何区分不同的方法?有一个methodID,但是递归调用呢?方法打开后什么时候关闭?
我应该比较堆栈跟踪吗?什么是有意义的数据结构来跟踪输入的方法?就像是Map<StackTrace,Time>?
java - 分析与检测 - Java
基本问题:JVM 提供了 JVMTI 用于分析和调试 JVM 的原生 API。JVM 检测也做同样的事情(对吗?)。如果是,两者有什么区别?
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。
java - 使用 JVMTI 的线程感知堆分配跟踪
编写分析我还将实现堆分析的典型任务。具体我想跟踪一下,哪个线程分配了多少数据?使用 JVMTI,我认为挂钩事件VM Object Allocation和Object Free就足够了。可悲的是,我读到第一个事件没有被触发,因为调用new
.
我的最后一个想法是检查事件MethodExit的名称是否为<init>
,从而将此调用声明为对象分配。但是,在此事件中,我无法获取对象,因此无法调用GetObjectSize
.
简单地遍历堆,不包含关于哪个对象由哪个线程分配的信息。有谁知道如何实现这个?