jdk自带的工具jvisualvm,可以分析java内存使用情况,jvm相关的信息。
1、设置jvm启动参数
设置jvm参数**-Xms20m -Xmx20m -XX:+PrintGCDetails** 最小和最大堆内存,打印gc详情
2、测试代码
TestScheduleClassGc
package com.core.schedule;
import com.core.Test.TestClassGC;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @auth admin
* @date 2023/2/15 19:21
*/
@Component
public class TestScheduleClassGc {
private static final AtomicInteger ATOMIC_INTEGER = new AtomicInteger(0);
private static final ExecutorService executorService = Executors.newFixedThreadPool(100);
@Scheduled(fixedRate = 1000)
private void print1() {
long xmsMemory = Runtime.getRuntime().totalMemory() / 1024 / 1024;
// Xms20m -Xm250m -XX:+PrintGCDetails
//返回Java虚拟机中使用的最大堆内存
long xmxMemory = Runtime.getRuntime().maxMemory() / 1024 / 1024;
long l = Runtime.getRuntime().freeMemory();
System.out.println("-Xms:" + xmsMemory + "M");
System.out.println("-Xmx:" + xmxMemory + "M");
System.out.println("-Xmx:" + l + "M");
for (int i = 0; i < 500; i++) {
// TestClassGC.anInt++;
executorService.execute(this::createGcLass);
}
}
private void createGcLass() {
LocalDateTime now1 = LocalDateTime.now();
System.out.println("Thread_name=" + Thread.currentThread().getName() + "||||||" + now1 + "==" + ATOMIC_INTEGER.incrementAndGet());
System.out.println();
TestClassGC testClassGC = new TestClassGC();
testClassGC.setName("xxxxxxxxxxxx" + ATOMIC_INTEGER.get());
try {
testClassGC.sleep();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
TestClassGC
package com.core.Test;
import java.util.concurrent.TimeUnit;
/**
* @auth admin
* @date 2023/2/15 19:20
*/
public class TestClassGC {
public static int anInt = 0;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void sleep() throws InterruptedException {
TimeUnit.SECONDS.sleep(1);
}
}
3、jvisualvm 连接java程序
jdk的安装路径下,双击左键即可启动
找到启动的程序双击连接即可使用,jvisualvm相关的功能菜单
概述、监视、线程相关的菜单栏
3、下面以监视简单说明
堆dump
jvm参数相关使用情况 ,堆dump可以保存为堆dump文件,保存下次导入使用
导出的dump文件,可以另存为,下次导入
4、观察类的实例数目
发现类的实例比较多,查看线程信息
看堆栈找到TestClassGC.java:22出现很多次,大胆猜测这里有问题。验证结论,分析代码。
找到对应的代码,是因为这里线程休眠,会阻塞很多的对象在线程队列中。队列 Executors.newFixedThreadPool(100) 创建完100个核心线程数,来的消息就会放入到阻塞队列。队列LinkedBlockingQueue无穷队列,导致对象堆积很多。
以上是jvisualvm工具的一个简单使用