java – 有没有办法知道特定程序运行的最大到达JVM调用堆栈深度?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java – 有没有办法知道特定程序运行的最大到达JVM调用堆栈深度?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2393字,纯文字阅读大概需要4分钟。
内容图文
![java – 有没有办法知道特定程序运行的最大到达JVM调用堆栈深度?](/upload/InfoBanner/zyjiaocheng/789/260a2791bcb0405db963ec8d4778f76e.jpg)
我今天编写了一个递归函数,递归深度取决于输入长度.
我从纯粹的兴趣观点来看,是否有某种方法可以监视,可能在某些JVM日志或其他地方,在特定程序执行期间最大调用堆栈深度是多少?
经过一番思考后,我可以想象一种分析方法来大致计算这个,但这将是非常耗时的,并且需要对JVM内部和字节码有很好的了解.
JVM允许配置堆栈大小内存的限制,但我从来没有见过任何关于如何获得实际达到的限制而不是内存大小单位但是分配的堆栈帧数.
解决方法:
可以轻松制作JVMTI代理,以跟踪MethodEntry/MethodExit事件并相应地增加或减少堆栈深度计数器.这是一个这样的代理的例子.程序结束时,它将打印最大记录的Java堆栈深度.
#include <jvmti.h>
#include <stdint.h>
#include <stdio.h>
static volatile int max_depth = 0;
static int adjust_stack_depth(jvmtiEnv *jvmti, int delta) {
intptr_t depth = 0;
(*jvmti)->GetThreadLocalStorage(jvmti, NULL, (void**)&depth);
(*jvmti)->SetThreadLocalStorage(jvmti, NULL, (const void*)(depth + delta));
return (int)depth;
}
void JNICALL MethodEntry(jvmtiEnv *jvmti, JNIEnv* jni, jthread thread, jmethodID method) {
adjust_stack_depth(jvmti, +1);
}
void JNICALL MethodExit(jvmtiEnv *jvmti, JNIEnv* jni, jthread thread, jmethodID method,
jboolean was_popped_by_exception, jvalue return_value) {
int depth = adjust_stack_depth(jvmti, -1);
if (depth > max_depth) {
max_depth = depth; // TODO: replace with atomic CAS to avoid race condition
}
}
JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void *reserved) {
jvmtiEnv* jvmti;
(*vm)->GetEnv(vm, (void**)&jvmti, JVMTI_VERSION_1_0);
jvmtiCapabilities capabilities = {0};
capabilities.can_generate_method_entry_events = 1;
capabilities.can_generate_method_exit_events = 1;
(*jvmti)->AddCapabilities(jvmti, &capabilities);
jvmtiEventCallbacks callbacks = {0};
callbacks.MethodEntry = MethodEntry;
callbacks.MethodExit = MethodExit;
(*jvmti)->SetEventCallbacks(jvmti, &callbacks, sizeof(callbacks));
(*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_METHOD_ENTRY, NULL);
(*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_METHOD_EXIT, NULL);
return 0;
}
JNIEXPORT void JNICALL Agent_OnUnload(JavaVM *vm) {
printf("Max stack depth = %d\n", max_depth);
}
编译:
gcc -fPIC -shared -I $JAVA_HOME/include -I $JAVA_HOME/include/linux -o libmaxdepth.so maxdepth.c
跑:
java -agentpath:/path/to/libmaxdepth.so MyProgram
但是,跟踪每个方法的进入和退出是非常昂贵的.一种不太准确但更有效的替代方案是采样分析器,它定期记录正在运行的线程的堆栈跟踪,例如, async-profiler或Java Flight Recorder.
内容总结
以上是互联网集市为您收集整理的java – 有没有办法知道特定程序运行的最大到达JVM调用堆栈深度?全部内容,希望文章能够帮你解决java – 有没有办法知道特定程序运行的最大到达JVM调用堆栈深度?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。