除了Java任务控制中更"先进"的GUI之外,它们有何不同?
乍一看,它们似乎提供了非常相似的功能(解释JMX数据和内存/ CPU分析).
但是,由于它们都随JDK一起提供(我使用的是JDK 1.7.0_51 SE),我假设存在显着差异,否则它们将合并为一个解决方案.特别是因为这会显着增加JDK的大小.
Java Mission Control最终是否会在未来取代JVisualVM?
我有一个Java程序,我正在努力改进.我怀疑代码中的同步块会损害性能,但我想在触摸代码之前确保这是我的问题.
为了检查同步块是否确实存在问题,我在带有Flight Recorder的测试服务器上记录了我的程序的执行情况,jfr
在桌面上下载了创建的文件并使用Java Mission Control打开它.但是Lock Instances
页面中Java Application
没有显示任何内容.我得到的唯一线索是结果视图中的一条消息:
Java阻止规则要求事件可从以下事件类型中获得:com.oracle.jdk.JavaMonitorEnter
因此,我假设必须有一些选项与飞行记录仪一起激活,但到目前为止我无法找到它.
如何启用com.oracle.jdk.JavaMonitorEnter
Java Flight Recorder记录的类型的事件?
或者我错过了其他的东西,并且有一种更好的方法来计算在Java程序中对同步块进行了多少阻塞?
我使用的是Oracle JDK 1.8.0_191版.我在桌面上使用的Java Mission Control版本是6.0.0.最后,我用来记录程序执行的命令如下:
java -XX:+UnlockCommercialFeatures -XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepoints -XX:+FlightRecorder -XX:StartFlightRecording=settings=profile,dumponexit=true,filename=test.jfr -classpath lib/*:src/ <my program with its arguments>
Run Code Online (Sandbox Code Playgroud)
我还应该补充说,使用Java Mission Control直接连接到服务器不是一个选项(或者是吗?),因为我使用ssh反弹实际连接到它...
我最近将我的REST API从Jersey 1迁移到Jersey 2(确切地说是2.22.1).该应用程序作为春季启动应用程序运行.该应用程序收到相当大的流量.我使用JMC(Java Mission Control)分析了应用程序,并注意到Annotations(getEntityAnnotations()
)消耗了大量内存.jms截图中的更多细节:
从屏幕截图中可以看到312个Annotation[]
对象拥有1.55 GB的内存(每个阵列大约5 MB).我在getEntityAnnotations()
方法中有突破点,并观察到Annotation[]
只包含3个注释(HTTP方法,路径和消耗).Annotation对象只有几个字段.我无法解释大字段的原因.调试器截图中的更多细节:
有没有人遇到过类似的问题?
除了jms截图,我们可以观察到一半的内存来自Arrays.copyOf
.这是因为类中的getEntityAnnotations()
方法OutboundMessageContext
克隆了entityAnnotations
数组.这个特殊的实施已添加到球衣2.5作为机票JERSEY-2072的一部分.
我正在使用Java 1.8.0_60和spring boot 1.3.2.RELEASE.如果您需要有关应用程序或环境的任何其他详细信息,请与我们联系
我在启动时通过为测试中的 Java 程序指定以下 CLI 选项来启动 JFR:
-Xmx24g -XX:+UnlockCommercialFeatures -XX:+FlightRecorder
-XX:FlightRecorderOptions=defaultrecording=true,dumponexit=true,settings=profile
Run Code Online (Sandbox Code Playgroud)
测试执行需要 90 秒才能完成。
在 Java Mission Control 中打开 JFR 转储后,JMC 中的“调用树”选项卡如下所示:
每秒少于 1 个样本。这使得详细的深入分析、热门方法和概述选项卡实际上毫无用处。经过初步调查,确定方法采样设置为默认值 10 毫秒,事实证明,这种意外结果是因为 90 秒中约 98% 的时间花在等待套接字 I/O 上,同时执行各种不同的数据库读取,所以我只在另外 2% 的时间内获取方法样本。
如何在方法时间中包含 I/O 密集型样本,以帮助找到花费最多时间等待数据库结果的跟踪?该过程包含多个地方的数据库查询,而这些查询又从多个其他地方调用,因此猜测缓慢的调用路径并不容易。
我正在努力使用自定义 JFR 事件对异步 servlet 请求处理进行建模。我面临的挑战是,在异步处理中,一个请求可能会被#dispatch()
多次编辑。这意味着整个请求处理链可能会被多次执行,在不同的线程中间隔一段时间。如何使用自定义 JFR 事件对此进行建模?
对我有帮助的是“父”事件的概念(可能在不同的线程中)或事件的暂停和恢复。
编辑
稍微说明一下这个问题。处理异步请求可能需要 100 秒挂钟时间。然而,在一个Servlet#service()
方法中,实际的处理可能只在 4 秒内发生:
Servlet#service()
方法返回,AsyncContext
开始Servlet#service()
方法返回,AsyncContext
开始Servlet#service()
方法返回,AsyncContext
开始Servlet#service()
方法返回我只对在这三个线程中为这四个持续时间生成事件感兴趣,然后将它们与单个请求相关联。
假设我使用以下标志为我的 JVM 配置了连续飞行记录
java
-XX:StartFlightRecording=disk=false,dumponexit=true
-XX:FlightRecorderOptions=memorysize=200m
-jar
....
Run Code Online (Sandbox Code Playgroud)
据我了解,此配置在内存中存储最多 200mb 的热点事件,当达到限制时会丢弃最旧的事件。
为了转储记录,我正在使用JFR.dump
命令 via jcmd
。还有一种通过任务控制提取记录的替代方法,但由于其中存在错误,我无法成功提取在任务控制的 JVM 外部运行的记录。令人惊讶的是,MBean 服务器管理运行良好。
无论如何,我发现可以通过任务控制的“转储”功能指定从连续记录转储的时间间隔范围,例如从 2021-01-01 13:00:00 到 2021-01-01 14:00: 00. 假设当前时间为 2021-01-02 17:00:00。如何通过 指定相同的间隔JFR.dump
?查看JFR.dump参考,没有任何标志可以执行此操作。那么任务控制中心是如何做到这一点的呢?
注意:我使用的是 JMC 8 和 Oracle JDK 11 0 10u8。
用于Java的(相对)新的内置性能监视器/分析器是Mission Control。在甲骨文的文档做广告,他们可以在生产中使用,而不会产生性能开销(不到2%):
工具链[Mission Control + Flight Recorder]使开发人员和管理员可以从本地运行或部署在生产环境中的Java应用程序收集和分析数据。
我已经使用jvisualvm
(VisualVM)多年了,但是由于在生产环境中可能会带来性能开销,所以人们从来没有使用过(VisualVM)。
所以我问:任务控制(及其飞行记录器)与VisualVM之间的区别是什么,它使MC / FR不会妨碍性能?还是它们不包括VisualVM提供的某些功能?
我有一个在远程机器上的容器中运行的 Spring Boot 应用程序,我必须使用哪些 JVM 参数通过 Java Mission Control 或 JVisual VM(通过 JMX)连接到它?
添加-XX:+FlightRecorder
到我的 CATALINA_OPTS 会导致我的 catalina.out 日志中出现此错误:
Error when initializing JFR. JFR will be deactivated.
java.lang.Exception: Unable to create JFR repository directory using base location (/var/cache/tomcat6/temp).
at oracle.jrockit.jfr.Repository.create(Repository.java:62)
at oracle.jrockit.jfr.Repository.<init>(Repository.java:26)
at oracle.jrockit.jfr.JFRImpl.<init>(JFRImpl.java:108)
at oracle.jrockit.jfr.VMJFR.<init>(VMJFR.java:55)
at oracle.jrockit.jfr.VMJFR.create(VMJFR.java:393)
at oracle.jrockit.jfr.JFR.init(JFR.java:91)
Error occurred during initialization of VM
Failed to start tracing backend.
Run Code Online (Sandbox Code Playgroud)
以下是完整的 CATALINA_OPTS /usr/share/tomcat8/bin/setenv.sh
:
export CATALINA_OPTS="-Dcom.sun.management.jmxremote=true \
-Dcom.sun.management.jmxremote.port=9090 \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.authenticate=false \
-Djava.rmi.server.hostname=10.202.210.173 \
-XX:+UnlockCommercialFeatures -XX:+FlightRecorder"
Run Code Online (Sandbox Code Playgroud)
如果我只启用该-XX:+UnlockCommercialFeatures
参数,tomcat实例不会崩溃,但是一旦我启用FlightRecorder,它就会崩溃。我也用 JAVA_OPTS 尝试过,得到了相同的结果。
我只是按照互联网上的教程为 Tomcat 启用 Flight Recorder,所以我真的不知道我可能做错了什么。在我看来,一切都很顺利。
这是在 64 位 CentOS …
java ×8
jfr ×4
jvisualvm ×3
jmc ×2
performance ×2
apm ×1
catalina ×1
docker ×1
java-11 ×1
java-8 ×1
jersey ×1
jersey-2.0 ×1
jmx ×1
jvm-hotspot ×1
profiling ×1
spring-boot ×1
tomcat ×1
tomcat8 ×1
visualvm ×1