`

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

    博客分类:
  • java
 
阅读更多

 

   场景,线上堆栈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

  • 大小: 254.9 KB
  • 大小: 218.3 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics