java老年代过多

应该是从java G1开始就没有具体的老年代了。

但是在工作中由于使用的是老的GC形式。还是出现了这个问题。下面记录一下自己发现问题,解决问题的方法。

 

  1. 首先下载生产环境dump
  2. 使用jvisual 打开dump。老年代持续过高,可能有两个原因
    1. 大对象过多。如果对象太大,会直接分配到老年代
    2. 代码中有leak,造成资源无法回收。
  3. 拿到dump后,看到了有很多 byte 数组过大。看了一下内容,是上传附件的内容导致的。下面是第一版上传附件的后端代码。

由于需要调用其他服务,所以要把request格式进行转化,不能直接透传。所以用到了ByteArrayResource。应该是转化成了这个地方转化的byte数组。没有及时的进行回收。

 

开始解决

方案一:

  1. 最开始打算查看http协议,直接用outputstream,直接写需要的数据。主要为了,不用读取字节数组。然后通过stream copy 减少内存使用。后来写了一点就放弃了。有点麻烦。
  2. 然后看了一下源代码,发现使用的是ByteArrayResource。我想直接使用其他的Resource代替就好了,应该有已经实现的这种累。然后找到了InputStreamResource。替换了以后,发现报错.do not use InputStreamResource if a stream needs to be read multiple times
  3. 我查看了一下代码,我应该没有使用InputStreamResource读取过内容。后来找了一篇帖子发现,AbstractResource读取长度的时候会调用inputSteam,代码如下。

  知道问题,然后避免读取inputStream就好了。重写 contentLeagth 方法。试了一下果然好用。

 

然后打开-XX:+PrintGC 。发现内存果然会减少。

实际效果,还得等到上线以后才可以查看效果。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值