有个项目zabbix报了一次“14:00 FGCT的时间超过前5分钟FGCT的时间(5s)”,赶紧上zabbix查看监控数据
发现java进程占用内存直接到2.6g,然后查看gc的情况
报警时间在下午2点,下午2点老年使用量到了1.3G左右,这个时候出发了fgc,gc后老年代恢复正常,没有发生内存泄漏,
但是java的常驻内存没有降下来,初步猜测java不会释放内存给操作系统,写个例子验证下自己的猜想
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000*10);
System.out.println("========");
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("111");
byte[] bytes0=new byte[512*1024*1014];
byte[] bytes1=new byte[512*1024*1014];
byte[] bytes2=new byte[512*1024*1014];
byte[] bytes3=new byte[512*1024*1014];
byte[] bytes4=new byte[512*1024*1014];
// 释放引用
bytes0=null;
bytes1=null;
bytes2=null;
bytes3=null;
bytes4=null;
try {
Thread.sleep(1000*10);
System.out.println("========");
} catch (InterruptedException e) {
e.printStackTrace();
}
// 触发gc
System.gc();
try {
Thread.sleep(1000*10);
System.out.println("========");
} catch (InterruptedException e) {
e.printStackTrace();
}
// // 再次申请空间
// bytes0=new byte[512*1024*1014];
// bytes1=new byte[512*1024*1014];
// bytes2=new byte[512*1024*1014];
// bytes3=new byte[512*1024*1014];
// bytes4=new byte[512*1024*1014];
}
}).start();
c.await();
gc后
gc后old区已经被清空,但是系统内存没有释放,gc后可再次申请空间,说明jvm的堆没有问题
所以说,java的进程res只能作为参考,还是得通过gc得情况分析问题,最后解决,通过dump下的文件发现堆区设置xmx2g xmn256m,年轻代过小,可以加大内存加大年轻代避免对象过早进入老年代