记一次线上服务器内存溢出排查

首先,这台服务器是我们的打印服务器,使用的是finereport7.0自带的webreport程序

背景是自从发布了一个供应商包装打印的功能后打印服务器经常内存溢出

首先在配置层面在系统启动时需要加上参数:

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/yapp/gc_log/

在奔溃时拿到java_pid27893.hprof文件

在eclipse中安装MAT工具,并打开该hprof文件

a7370cbef35aeebf7469938b4b17620269b.jpg

可以看到WebappClassLoader加载了3.9G的对象,点击Dominator Tree按钮查看最多占用内存的对象信息

3d9dce975e05b425a2d65fd72c60cf5cbcd.jpg

发现在finereport服务器的程序上叫BaseUtils的类下有个map的空间特别大,

查看源码

public class BaseUtils
{
  public static final String RESOURCE_ENCODER = "GBK";
  private static Map imageMap = new HashMap();
  
  public static BufferedImage readImageWithCache(String paramString)
  {
    return readImage(paramString, true);
  }
  
  private static BufferedImage readImage(String paramString, boolean paramBoolean)
  {
    Object localObject = null;
    if (paramBoolean) {
      localObject = imageMap.get(paramString);
    }
    if ((localObject instanceof BufferedImage)) {
      return (BufferedImage)localObject;
    }
    InputStream localInputStream = readResource(paramString);
    if (localInputStream == null) {
      return null;
    }
    BufferedImage localBufferedImage = null;
    try
    {
      localBufferedImage = readImage(localInputStream);
      localInputStream.close();
    }
    catch (IOException localIOException)
    {
      FRContext.getLogger().error(localIOException.getMessage(), localIOException);
    }
    if (paramBoolean) {//对图片进行缓存,并且不进行释放,从而导致报表中打印的图片越来越多的时候会越来越占内存
      imageMap.put(paramString, localBufferedImage);
    }
    return localBufferedImage;
  }

从MAT分析中看到,String参数表示图片的地址信息,BufferedImage对象则是图片字节流,比如有张图片的地址是http://bfile.srm.xxx.com/group1/M00/00/25/ClbY8Fyuzm2AAkXVAP5Nj6sa3E0749.png

打开显示是张彩色图片,另存为图片后有17MB大,因此如果用户持续使用改打印显示图片功能,并且图片数量不断累积的话是会导致越来越多的内存被占用并且得不到释放的

后查看fineReport的函数文档,对于在打印报表显示图片的功能来说有个toImage函数可加上false参数来指定不对打印报表中要显示的图片进行缓存,从而避免该问题的发生。

转载于:https://my.oschina.net/ffse54s/blog/3050247

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值