java - JVM 以编程方式获取分配调用堆栈

原文 标签 java jvm profiling heap-memory profiler

这是 this one 的后续问题
因此,我不断从“程序化访问”的角度探索现代分析器的功能,并且遇到了一些超出我理解的东西。
这次我偶然发现了 JProfiler 中的“分配调用树”功能:
Allocation Call Tree
我确实看到,为了获得这种信息,我必须默认以 1/10 的速率触发采样分配,然后指定(最好)将记录分配的分类的包。
第一步
Step 1
第二步
Step 2
但是我真的不明白有关调用堆栈的信息如何与有关分配对象的信息“匹配”。
当然,我的问题不是关于 JProfiler 的实现细节,我理解它是一个商业工具,代码和一切都很接近,而是关于如何检索这种信息的一般理解。
我最初的猜测是,它以某种方式“检测”已经加载的类文件以“拦截”这些对象的每个分配(采样率不会太慢)但是然后呢?它是否调用类似 Thread.currentThread().getStackTrace()并记录导致分配的实际堆栈跟踪?
另一方面,它在“采样模式”(与仪器相反)中激活+存在性能问题 - 这对我来说听起来非常昂贵(阅读,不应该在生产中使用),但我可能是错误的,所以任何建议将不胜感激。

最佳答案

My initial guess is that it somehow "instruments" the already-loaded class files to "intercept" each and every allocation for these objects


自 Java 11 交付以来 JEP 331它在 native JVMTI 中使用这些功能来采样分配。在 Java 11 之前,它检测 java.lang.Object构造函数。至于调用堆栈,这取决于使用的是检测还是采样。对于检测,它使用检测已经构建的调用堆栈。对于采样,采样构建的调用栈不够精确,所以queries the call stack through JVMTI .

Does it call something like Thread.currentThread().getStackTrace()


对于采样,它有点像那样,但是在 Java 中这样做会产生巨大的开销,因为有许多二级分配。 JVMTI 是 native 接口(interface),可以更有效地执行此操作。

关于java - JVM 以编程方式获取分配调用堆栈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67156225/

相关文章:

java - Java Paths.get…readAllBytes(path))无法使用相对路径

java - 如何在while循环之外,在while循环中,在方法内部始终访问字符串值

java - 使用BCEL的错误“java.lang.VerifyError:StackMapTable错误:错误的偏移量”

java - Kotlin - 无法创建两个具有不同列表类型参数的构造函数

crash - 应用程序实例由于Hibernate session.createQuery()而终止

java - 将像素值转换为 RGB 格式

linux - 高度时间敏感应用的分析方法

c - 如何告诉 gcc 通过调用我自己的函数来检测代码的每个 _line_ 代码?

clojure - Clojure 的分析工具?

java - 用于子请求的 CompletableFuture