这个工具我发现在Oracle JDK8以上没有,通过查询资料需要自己去安装集成
官网文档使用手册
https://docs.oracle.com/en/java/java-components/jdk-mission-control/8/user-guide/installing-jdk-mission-control-and-supported-plugins.html#GUID-2C820B29-3FF3-4ED2-8E3E-DD732303E4A4
Install JMC Standalone Application
Prerequisites
Install JDK 11 64-bit (or later); see Download and License Information.
Ensure that you set the <jdk_installation_path>/bin PATH environment variable and the $TEMP directory is accessible.
For configuration details, see JDK Mission Control 8 Installation Instructions.
我目前是Windows环境,因此我进行windows相关的配置
在JMC文件夹下有一个名称为jmc.ini的配置文件
编辑改文件,按文档提示需要加入指定本地JDK路径
Ensure it is added just before the
-vmargs flag.
-vm
C:\Program Files\Java\jdk-11.0.13\bin
-vmargs
配置示例
-startup
plugins/org.eclipse.equinox.launcher_1.6.100.v20201223-0822.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.win32.win32.x86_64_1.2.100.v20210209-1541
--launcher.appendVmargs
-vm
D:\jdk\JDK11\bin
-vmargs
-XX:+IgnoreUnrecognizedVMOptions
-XX:+UnlockDiagnosticVMOptions
-XX:+DebugNonSafepoints
-XX:FlightRecorderOptions=stackdepth=128
-XX:+FlightRecorder
-XX:StartFlightRecording=name=JMC_Default,maxsize=100m
-Djava.net.preferIPv4Stack=true
-Djdk.attach.allowAttachSelf=true
--add-exports=java.xml/com.sun.org.apache.xerces.internal.parsers=ALL-UNNAMED
--add-exports=jdk.internal.jvmstat/sun.jvmstat.monitor=ALL-UNNAMED
--add-exports=java.management/sun.management=ALL-UNNAMED
--add-exports=java.management/sun.management.counter.perf=ALL-UNNAMED
--add-exports=jdk.management.agent/jdk.internal.agent=ALL-UNNAMED
--add-exports=jdk.attach/sun.tools.attach=ALL-UNNAMED
--add-opens=java.base/java.net=ALL-UNNAMED
--add-opens=jdk.attach/sun.tools.attach=ALL-UNNAMED
-Dsun.java.command=JMC
--add-exports=java.desktop/sun.awt.windows=ALL-UNNAMED
1.启动jmc
可以找到bin下exe启动,也可以通过配置到环境变量里进行命令行jmc启动
2.我们通过示例来简单看下如何使用JMC
XX:+UnlockCommercialFeatures -XX:+FlightRecorder
import java.util.concurrent.*;
public class MemoryLeak {
// no limit!
private static BlockingQueue<byte[]> queue = new LinkedBlockingQueue<>();
public static void main(String[] args) {
Runnable producer = () -> {
while (true) {
// generates 1mb of object every 10ms
queue.offer(new byte[1 * 1024 * 1024]);
try {
TimeUnit.MILLISECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Runnable consumer = () -> {
while (true) {
try {
// process every 100ms
queue.take();
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
// give a name, good for profiling
new Thread(producer, "Producer Thread").start();
new Thread(consumer, "Consumer Thread").start();
}
}
通过测试生成的JFR数据如下
如下是MBean数据
即使不考虑对被测试程序性能影响方面的优势,JFR提供的数据质量通常也要比其他工具通过代 理形式采样获得或者从MBean中取得的数据高得多。以垃圾搜集为例,HotSpot的MBean中一般有各个 分代大小、收集次数、时间、占用率等数据(根据收集器不同有所差别),这些都属于“结果”类的信 息,而JFR中还可以看到内存中这段时间分配了哪些对象、哪些在TLAB中(或外部)分配、分配速率 和压力大小如何、分配归属的线程、收集时对象分代晋升的情况等,这些就是属于“过程”类的信息, 对排查问题的价值是难以估量的。