您的位置:首页 > 其它

系统频繁Full gc问题分析及解决办法

2017-01-18 15:03 501 查看
一、场景描述
上周开始系统在业务高峰期一直收到Full gc报警,监控显示fgc频繁,下图是监控图,左边红框是优化前效果,右边是优化后,优化后fgc基本为0




二、原因查找

1.查看gc日志,发现old区fgc后大小没有变化,如下图:




2.去线上dump内存看是什么对象,用memory analyzer分析,Retained Size竟然有2.4G,全是sun.awt.SunToolkit这个对象,其实到这一步已经可以确定是什么问题了,只是自己对系统不是很熟悉,导致定位具体的问题代码花了一些时间



三、原因分析
系统中有一个调用频繁的接口会调用下面这个方法,目的是获取图片的宽高信息,但是Image这个对象用完不会自动释放,需要手动调用 flush()方法;以前没有调用这个方法,就导致一有请求就会有大对象进入old区,在业务高峰期old区一会就被打满,所以一直进行fgc 

public static Image getImage(String path) { 

ImageIcon icon = new ImageIcon(path); 

Image img = icon.getImage(); 

return img; 

}
四、解决办法
其实不管是用Image还是BufferedImage,读取图片的宽高不用把图片全部加载到内存,在图片的宽高信息其实是存储在文件头中的,只 要按不同的格式读取文件的头信息就可以拿到宽高信息 

使用ImageReader代码如下
Iterator readers = ImageIO.getImageReadersByFormatName(StringUtil.getFileSuffix(filePath)); 

ImageReader reader = (ImageReader)readers.next(); 

iis = ImageIO.createImageInputStream(is); 

reader.setInput(iis, true); 

return Pair.of(reader.getWidth(0),reader.getHeight(0));
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: