使用 ObjectOutputStream 可能引起的内存泄漏

 

   场景,线上堆栈10G,平时内存使用达到8个G而且慢慢增长,经常出现full gc,经过堆栈信息排查出来是由于ObjectOutputStream造成得内存泄漏。项目中使用ObjectOutputStream进行写文件,使用writeObject()方法,然而,该对象写得object可能存在内存泄漏,是由于ObjectOutputStream写对象时,依然存在这对该对象得引用,这是java得自身优化,可以减少socket得网络开销,譬如如下代码,然后看截图,我们虽然写了10次,但是并不是每次都会记录对象和成员变量得信息,而是第一次记录,之后不再记录,这时java得优化,减少socket网络开销,然而可以这么做时因为该outputstream持有myobject得引用,当数据量很大得时候必然会产生内存泄漏。

解决方法是,使用reset方法,重置状态,第二张图片就是重置后得信息,很明显,使用reset后,会增加网络网络开销,所以对于是否使用reset方法,请根据实际业务决定,当长期不停服务,最好使用reset,而对于短期内停止服务,数据量很大得,可以不是用reset。

当数量为1000000时,内存使用两下图。

内容参考如下引用:

http://www.ibm.com/developerworks/cn/java/j-lo-streamleak/

public static void main(String[] args) throws IOException {

FileOutputStream fos = new FileOutputStream("test.txt"); 

ObjectOutputStream oos = new ObjectOutputStream(fos); 

//try {

//Thread.sleep(20000);

//} catch (InterruptedException e2) {

TODO Auto-generated catch block

//e2.printStackTrace();

//}

System.out.println(new Date());

 

//for (int i = 0; i < 1000000; i++) { 

for (int i = 0; i < 10; i++) {

MyObject myObj = new MyObject(); 

myObj.str1 = "test1"

myObj.str2 = "test2";

    oos.writeObject(myObj); 

//    oos.reset();

try {

Thread.sleep(20000);

System.out.println(new Date());

} catch (InterruptedException e1) {

// TODO Auto-generated catch block

e1.printStackTrace();

}

fos.close();

try {

Thread.sleep(20000);

System.out.println(new Date());

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

 

}

 

没使用reset

使用reset

 

未使用reset 次数100w

 

使用reset,次数100w

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值