Comments (22)
cn.myperf4j.asm.aop.ProfilingTransformer#getBytes
private byte[] getBytes(ClassLoader loader,
String className,
byte[] classFileBuffer) {
ClassReader cr = new ClassReader(classFileBuffer);
ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS) {
@Override
protected ClassLoader getClassLoader() {
return Thread.currentThread().getContextClassLoader();
}
};
ClassVisitor cv = new ProfilingClassAdapter(cw, className);
cr.accept(cv, ClassReader.EXPAND_FRAMES);
return cw.toByteArray();
}
采用线程本地类加载器后,自测在 tomcat 8.5 上可以监控 tomcat 本身和内部类
此处的改动就限制死了加载的class文件必须是使用 jdk 1.7 以上版本编译过的
see: https://www.java67.com/2020/04/javalangverifyerror-expecting-stack-map.html
from myperf4j.
现在 MyPerf4J 只支持 1.7 及其之上的版本,这个改动的影响面比较大,你测试了哪些场景?
这块代码逻辑兼容了 PlainJava、Tomcat、SpringBoot、Flink 等场景,如果你的解决方案同样适用这些场景的话,欢迎提交 PR
from myperf4j.
前三者没问题,Flink 没环境测。。。
from myperf4j.
这种写法你是在哪儿看到的?当年我写这段代码的时候对于使用 COMPUTE_MAXS 还是 COMPUTE_FRAMES 还是比较困惑的
from myperf4j.
堆栈显示这报的错,看了下里面有获取 ClassLoader 的方法,就试了下
那俩变量就 google 下,看到了那篇文章的内容😁
from myperf4j.
有想法、运气不错;不过,你这个改动得进行全面的测试才行
from myperf4j.
翻了下文档,读的时候不需要计算,要不会有性能损耗,写的时候才重新计算
private byte[] getBytes(ClassLoader loader,
String className,
byte[] classFileBuffer) {
ClassReader cr = new ClassReader(classFileBuffer);
ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES) {
@Override
protected ClassLoader getClassLoader() {
return Thread.currentThread().getContextClassLoader();
}
};
ClassVisitor cv = new ProfilingClassAdapter(cw, className);
cr.accept(cv, ClassReader.SKIP_FRAMES);
return cw.toByteArray();
}
from myperf4j.
翻了下文档,读的时候不需要计算,要不会有性能损耗,写的时候才重新计算
from myperf4j.
这是跟其它的 agent 冲突了吧,我本地用 jdk20 起了一个 springboot2.7.8 的 demo 没问题
from myperf4j.
出现了个这问题😓
2023-04-10 22:38:00.014 [MyPerf4J] ERROR [MyPerf4J-LightWeightScheduler-0] JvmMetricsScheduler.processThreadMetrics(1681137420014, 1681137420014, 1681137480014) Could not initialize class cn.myperf4j.base.metric.collector.JvmThreadCollector
java.lang.NoClassDefFoundError: Could not initialize class cn.myperf4j.base.metric.collector.JvmThreadCollector
at cn.myperf4j.core.scheduler.JvmMetricsScheduler.processThreadMetrics(JvmMetricsScheduler.java:139)
at cn.myperf4j.core.scheduler.JvmMetricsScheduler.run(JvmMetricsScheduler.java:72)
at cn.myperf4j.core.LightWeightScheduler.runTask(LightWeightScheduler.java:100)
at cn.myperf4j.core.LightWeightScheduler.runAllTasks(LightWeightScheduler.java:93)
at cn.myperf4j.core.LightWeightScheduler.access$200(LightWeightScheduler.java:18)
at cn.myperf4j.core.LightWeightScheduler$1.run(LightWeightScheduler.java:85)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:577)
at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:358)
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1623)
Caused by: java.lang.ExceptionInInitializerError: Exception java.lang.reflect.InaccessibleObjectException: Unable to make private static native java.lang.Thread[] java.lang.Thread.getThreads() accessible: module java.base does not "opens java.lang" to unnamed module @6a41eaa2 [in thread "MyPerf4J-LightWeightScheduler-1"]
at java.base/java.lang.reflect.AccessibleObject.throwInaccessibleObjectException(AccessibleObject.java:387)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:363)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:311)
at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:201)
at java.base/java.lang.reflect.Method.setAccessible(Method.java:195)
at cn.myperf4j.base.metric.collector.JvmThreadCollector.reflectGetThreadsMethod(JvmThreadCollector.java:34)
at cn.myperf4j.base.metric.collector.JvmThreadCollector.<clinit>(JvmThreadCollector.java:27)
... 12 more
from myperf4j.
ThreadMXBean 里面不是有现成的方法可以获取到数据么,为啥要反射呢?
from myperf4j.
这是跟其它的 agent 冲突了吧,我本地用 jdk20 起了一个 springboot2.7.8 的 demo 没问题
不是
from myperf4j.
出现了个这问题😓
2023-04-10 22:38:00.014 [MyPerf4J] ERROR [MyPerf4J-LightWeightScheduler-0] JvmMetricsScheduler.processThreadMetrics(1681137420014, 1681137420014, 1681137480014) Could not initialize class cn.myperf4j.base.metric.collector.JvmThreadCollector java.lang.NoClassDefFoundError: Could not initialize class cn.myperf4j.base.metric.collector.JvmThreadCollector at cn.myperf4j.core.scheduler.JvmMetricsScheduler.processThreadMetrics(JvmMetricsScheduler.java:139) at cn.myperf4j.core.scheduler.JvmMetricsScheduler.run(JvmMetricsScheduler.java:72) at cn.myperf4j.core.LightWeightScheduler.runTask(LightWeightScheduler.java:100) at cn.myperf4j.core.LightWeightScheduler.runAllTasks(LightWeightScheduler.java:93) at cn.myperf4j.core.LightWeightScheduler.access$200(LightWeightScheduler.java:18) at cn.myperf4j.core.LightWeightScheduler$1.run(LightWeightScheduler.java:85) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:577) at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:358) at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) at java.base/java.lang.Thread.run(Thread.java:1623) Caused by: java.lang.ExceptionInInitializerError: Exception java.lang.reflect.InaccessibleObjectException: Unable to make private static native java.lang.Thread[] java.lang.Thread.getThreads() accessible: module java.base does not "opens java.lang" to unnamed module @6a41eaa2 [in thread "MyPerf4J-LightWeightScheduler-1"] at java.base/java.lang.reflect.AccessibleObject.throwInaccessibleObjectException(AccessibleObject.java:387) at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:363) at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:311) at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:201) at java.base/java.lang.reflect.Method.setAccessible(Method.java:195) at cn.myperf4j.base.metric.collector.JvmThreadCollector.reflectGetThreadsMethod(JvmThreadCollector.java:34) at cn.myperf4j.base.metric.collector.JvmThreadCollector.<clinit>(JvmThreadCollector.java:27) ... 12 more
注意看:module java.base does not "opens java.lang" to unnamed module
from myperf4j.
ThreadMXBean 里面不是有现成的方法可以获取到数据么,为啥要反射呢?
性能差,线程数很多时会影响应用
from myperf4j.
这是跟其它的 agent 冲突了吧,我本地用 jdk20 起了一个 springboot2.7.8 的 demo 没问题
不是
有复现的 demo 么,图里也看不出啥来,或者加载的那个类有啥特别的
from myperf4j.
这是跟其它的 agent 冲突了吧,我本地用 jdk20 起了一个 springboot2.7.8 的 demo 没问题
不是
有复现的 demo 么,图里也看不出啥来,或者加载的那个类有啥特别的
从代码上看没什么特别的:
class A extends B
- 在加载 B 时抛出
java.lang.ClassCircularityError: A
from myperf4j.
你试试这个方案:
private byte[] getBytes(final ClassLoader loader,
String className,
byte[] classFileBuffer) {
final ClassReader cr = new ClassReader(classFileBuffer);
final ClassWriter cw = new ClassWriter(cr, needComputeMaxs(loader) ? COMPUTE_MAXS : COMPUTE_FRAMES) {
@Override
protected ClassLoader getClassLoader() {
return loader != null ? loader : super.getClassLoader();
}
};
final ClassVisitor cv = new ProfilingClassAdapter(cw, className);
cr.accept(cv, EXPAND_FRAMES);
return cw.toByteArray();
}
from myperf4j.
这是跟其它的 agent 冲突了吧,我本地用 jdk20 起了一个 springboot2.7.8 的 demo 没问题
不是
有复现的 demo 么,图里也看不出啥来,或者加载的那个类有啥特别的
从代码上看没什么特别的:
class A extends B
- 在加载 B 时抛出
java.lang.ClassCircularityError: A
那说明 B extends A ? 要么类库出现了多个版本了
from myperf4j.
这是跟其它的 agent 冲突了吧,我本地用 jdk20 起了一个 springboot2.7.8 的 demo 没问题
不是
有复现的 demo 么,图里也看不出啥来,或者加载的那个类有啥特别的
从代码上看没什么特别的:
class A extends B
- 在加载 B 时抛出
java.lang.ClassCircularityError: A
那说明 B extends A ? 要么类库出现了多个版本了
B 不会继承 A 否则编译都通不过;还是类加载的问题
from myperf4j.
-XX:+TraceClassLoading 看下没 agent 的时候和有 agent 的时候那个类是从哪加载的。。。剩下我能想到的就只有那个类所在的类库出现了多个版本了,最好提供个 demo 吧😢
from myperf4j.
@JiaRG
如果以这个为 v0.1:
private byte[] getBytes(final ClassLoader loader,
String className,
byte[] classFileBuffer) {
final ClassReader cr = new ClassReader(classFileBuffer);
final ClassWriter cw = new ClassWriter(cr, needComputeMaxs(loader) ? COMPUTE_MAXS : COMPUTE_FRAMES) {
@Override
protected ClassLoader getClassLoader() {
return loader != null ? loader : super.getClassLoader();
}
};
final ClassVisitor cv = new ProfilingClassAdapter(cw, className);
cr.accept(cv, EXPAND_FRAMES);
return cw.toByteArray();
}
以这个为 v1:
private byte[] getBytes(ClassLoader loader,
String className,
byte[] classFileBuffer) {
ClassReader cr = new ClassReader(classFileBuffer);
ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES) {
@Override
protected ClassLoader getClassLoader() {
return Thread.currentThread().getContextClassLoader();
}
};
ClassVisitor cv = new ProfilingClassAdapter(cw, className);
cr.accept(cv, ClassReader.SKIP_FRAMES);
return cw.toByteArray();
}
那么,在没有 MyPerf4J 和 有 MyPerf4J v0.1 与 v1 的版本在添加了 -XX:+TraceClassLoading 参数后的日志(做了脱敏与过滤)为:
你可以看到有问题的 v1 版本的类加载与另外两个明显不同,v1 版本里 MqttWireMessage 加载了 2 次
from myperf4j.
你试试这个方案:
private byte[] getBytes(final ClassLoader loader, String className, byte[] classFileBuffer) { final ClassReader cr = new ClassReader(classFileBuffer); final ClassWriter cw = new ClassWriter(cr, needComputeMaxs(loader) ? COMPUTE_MAXS : COMPUTE_FRAMES) { @Override protected ClassLoader getClassLoader() { return loader != null ? loader : super.getClassLoader(); } }; final ClassVisitor cv = new ProfilingClassAdapter(cw, className); cr.accept(cv, EXPAND_FRAMES); return cw.toByteArray(); }
@JiaRG 这个 v0.1 的版本,你试了么?
from myperf4j.
Related Issues (20)
- grafana没有数据,怎么排查influxdb是否写入成功? HOT 9
- Flaky test testMultiThread4HighRace and testMultiThread4LowRace HOT 1
- 请问 http.influxdb 可以支持 influxdb V2.0 的 token模式吗 HOT 2
- influxdb表中写入了数据,grafana页面使用MyPerf4J模板无法展示数据 HOT 5
- 已经整合了grafana、influxdb,MyPerf4J已经往influxdb表中写入了数据,grafana页面使用MyPerf4J模板无法展示数据 HOT 5
- 请问不同应用是否可复用同一配置文件,app_name如何设置 HOT 3
- 是否支持Promethus 以及对应配置模板 HOT 1
- 使用influxdb 2.x以上,怎么配置才能链接 HOT 3
- 应用启动报错 HOT 1
- tomcat8.5没有打出日志 HOT 8
- window环境下配置文件路径获取错误 HOT 1
- File.renameTo及File.setReadOnly的问题 HOT 6
- 请问可否加入接口的耗时统计,统计系统每个接口性能测试中时间 HOT 8
- 你好,请问这个工具,可以跟踪到k8s容器里面的JVM的各种信息吗? HOT 1
- 希望支持一下jdk-17 HOT 3
- MyPer4j支持异步模型的jvm进程监控吗,例如webflux HOT 1
- 你好 请问SpringMVC的项目支持嘛 HOT 2
- 你好,请问可否把配置文件做成一个UI界面的操作,方便管理 HOT 3
- WIKI文档里面的http配置 HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from myperf4j.