基于Java的agent 技术获取JVM和GC信息
有时候我们需要对线上的JVM信息以及GC信息进行统计。基于Java的agent 技术可以实现。
1. 新建agent 相关的类
- 工具类
package org.example.jvmdebug;
import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
import java.util.Arrays;
import java.util.List;
public class JvmStack {
private static final long MB = 1048576L;
static void printMemoryInfo() {
MemoryMXBean memory = ManagementFactory.getMemoryMXBean();
MemoryUsage headMemory = memory.getHeapMemoryUsage();
String info = String.format("\ninit: %s\t max: %s\t used: %s\t committed: %s\t use rate: %s\n",
headMemory.getInit() / MB + "MB",
headMemory.getMax() / MB + "MB", headMemory.getUsed() / MB + "MB",
headMemory.getCommitted() / MB + "MB",
headMemory.getUsed() * 100 / headMemory.getCommitted() + "%"
);
System.out.print(info);
MemoryUsage nonheadMemory = memory.getNonHeapMemoryUsage();
info = String.format("init: %s\t max: %s\t used: %s\t committed: %s\t use rate: %s\n",
nonheadMemory.getInit() / MB + "MB",
nonheadMemory.getMax() / MB + "MB", nonheadMemory.getUsed() / MB + "MB",
nonheadMemory.getCommitted() / MB + "MB",
nonheadMemory.getUsed() * 100 / nonheadMemory.getCommitted() + "%"
);
System.out.println(info);
}
static void printGCInfo() {
List<GarbageCollectorMXBean> garbages = ManagementFactory.getGarbageCollectorMXBeans();
for (GarbageCollectorMXBean garbage : garbages) {
String info = String.format("name: %s\t count:%s\t took:%s\t pool name:%s",
garbage.getName(),
garbage.getCollectionCount(),
garbage.getCollectionTime(),
Arrays.deepToString(garbage.getMemoryPoolNames()));
System.out.println(info);
}
}
}
- 对外暴露的agent
package org.example.jvmdebug;
import java.lang.instrument.Instrumentation;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class MyAgent {
private static AtomicInteger TIMES = new AtomicInteger();
public static void premain(String agentArgs, Instrumentation inst) {
System.out.println("this is my agent:" + agentArgs);
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {
public void run() {
System.out.println("===================================================================================================" + TIMES.addAndGet(1));
JvmStack.printMemoryInfo();
JvmStack.printGCInfo();
}
}, 0, 5, TimeUnit.SECONDS);
}
}
2. 将jar 包打包
- 修改pom
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestEntries>
<addClasspath>true</addClasspath>
<Premain-Class>org.example.jvmdebug.MyAgent</Premain-Class>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
<Can-Redefine-Classes>true</Can-Redefine-Classes>
<Can-Retransform-Classes>true</Can-Retransform-Classes>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
- 打包
mvn clean package
- 打包包,解压后查看
META-INF/MANIFEST.MF文件如下:
Manifest-Version: 1.0
addDefaultSpecificationEntries: true
addClasspath: true
Premain-Class: org.example.jvmdebug.MyAgent
Archiver-Version: Plexus Archiver
Built-By: xxx
Can-Redefine-Classes: true
addDefaultImplementationEntries: true
Can-Retransform-Classes: true
Created-By: Apache Maven 3.8.1
Build-Jdk: 1.8.0_351
3. 测试
package org.example.jvmdebug;
public class JvmStackTest {
private static final int _MB = 1024 * 1024;
public static void main(String[] args) throws InterruptedException {
while (true) {
Thread.sleep(5 * 1000);
byte[] bytes = new byte[10 * _MB];
}
}
}
修改JVM参数增加agent:
-javaagent:/Users/xxx/Desktop/jvmdebug/mvnpro-1.0-SNAPSHOT.jar
查看日志:
this is my agent:null
===================================================================================================1
init: 256MB max: 3641MB used: 5MB committed: 245MB use rate: 2%
init: 2MB max: 0MB used: 5MB committed: 7MB use rate: 68%
name: PS Scavenge count:0 took:0 pool name:[PS Eden Space, PS Survivor Space]
name: PS MarkSweep count:0 took:0 pool name:[PS Eden Space, PS Survivor Space, PS Old Gen]
===================================================================================================2
init: 256MB max: 3641MB used: 7MB committed: 245MB use rate: 3%
init: 2MB max: 0MB used: 5MB committed: 7MB use rate: 69%
name: PS Scavenge count:0 took:0 pool name:[PS Eden Space, PS Survivor Space]
name: PS MarkSweep count:0 took:0 pool name:[PS Eden Space, PS Survivor Space, PS Old Gen]
===================================================================================================3
init: 256MB max: 3641MB used: 17MB committed: 245MB use rate: 7%
init: 2MB max: 0MB used: 5MB committed: 7MB use rate: 69%
name: PS Scavenge count:0 took:0 pool name:[PS Eden Space, PS Survivor Space]
name: PS MarkSweep count:0 took:0 pool name:[PS Eden Space, PS Survivor Space, PS Old Gen]
===================================================================================================4
init: 256MB max: 3641MB used: 27MB committed: 245MB use rate: 11%
init: 2MB max: 0MB used: 5MB committed: 7MB use rate: 70%
name: PS Scavenge count:0 took:0 pool name:[PS Eden Space, PS Survivor Space]
name: PS MarkSweep count:0 took:0 pool name:[PS Eden Space, PS Survivor Space, PS Old Gen]
===================================================================================================5
init: 256MB max: 3641MB used: 37MB committed: 245MB use rate: 15%
init: 2MB max: 0MB used: 5MB committed: 7MB use rate: 70%
name: PS Scavenge count:0 took:0 pool name:[PS Eden Space, PS Survivor Space]
name: PS MarkSweep count:0 took:0 pool name:[PS Eden Space, PS Survivor Space, PS Old Gen]
===================================================================================================6
init: 256MB max: 3641MB used: 47MB committed: 245MB use rate: 19%
init: 2MB max: 0MB used: 5MB committed: 7MB use rate: 70%
name: PS Scavenge count:0 took:0 pool name:[PS Eden Space, PS Survivor Space]
name: PS MarkSweep count:0 took:0 pool name:[PS Eden Space, PS Survivor Space, PS Old Gen]
===================================================================================================7
init: 256MB max: 3641MB used: 57MB committed: 245MB use rate: 23%
init: 2MB max: 0MB used: 5MB committed: 7MB use rate: 70%
name: PS Scavenge count:0 took:0 pool name:[PS Eden Space, PS Survivor Space]
name: PS MarkSweep count:0 took:0 pool name:[PS Eden Space, PS Survivor Space, PS Old Gen]
===================================================================================================8
init: 256MB max: 3641MB used: 11MB committed: 245MB use rate: 4%
init: 2MB max: 0MB used: 5MB committed: 7MB use rate: 70%
name: PS Scavenge count:1 took:8 pool name:[PS Eden Space, PS Survivor Space]
name: PS MarkSweep count:0 took:0 pool name:[PS Eden Space, PS Survivor Space, PS Old Gen]
...
【当你用心写完每一篇博客之后,你会发现它比你用代码实现功能更有成就感!】