`

使用 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
分享到:
评论

相关推荐

    socket objectoutputstream 传对象 例子

    在Java编程中,Socket和ObjectOutputStream是两个非常重要的概念,它们是进行网络通信的基础。Socket是TCP/IP协议的实现,提供了两台计算机之间双向、独立的数据传输通道。而ObjectOutputStream则是一个序列化流,...

    JAVA内存溢出详解.doc

    - **内存泄漏检测**:使用内存分析工具,如VisualVM、MAT(Memory Analyzer Tool)等,找出程序中的内存泄漏问题。 4. **垃圾收集机制** Java的垃圾收集器负责自动回收不再使用的对象所占用的内存。了解并优化...

    websphere性能分析

    - **ObjectOutputStream**:如果序列化处理不当,可能导致内存消耗过大。 5. **解决方案**: - **生成dump文件**:使用wsadmin脚本客户端的generateHeapDump操作。 - **并发读取配置文件**:确保CAS并发读取配置...

    java学习笔记(java 反射机制 流 内存管理)

    内存泄露是常见的问题,当不再使用的对象仍然被引用,无法被垃圾收集器回收。此外,栈内存用于存储方法局部变量,随着方法的调用和返回自动管理。 四、基础Java学习 学习Java的基础涉及语法、控制结构、异常处理、...

    JavaIOObjectStreams:FileInputStream 与 ObjectInputStream 和 ObjectOutputStream 的组合

    要序列化一个对象,你需要实现Serializable接口,然后使用ObjectOutputStream的writeObject()方法: ```java try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("serialized_object.ser...

    java面试大总结(3)[定义].pdf

    真正的内存泄漏可能发生在不再使用的对象引用被意外保持,导致GC无法回收这些对象占用的内存。 Java中的多态性体现在方法的重写(Overriding)和重载(Overloading)。重写是指子类可以提供与父类相同签名的方法,但...

    java大字段转换

    处理大字段时需要特别注意内存管理,因为它们可能导致内存溢出(Out Of Memory)问题,影响应用的性能和稳定性。这篇博客文章可能详细探讨了如何在Java中有效地处理大字段,以及可能遇到的相关挑战。 1. **大字段...

    java-deserialize-recovery:该项目旨在恢复使用java.io.ObjectOutputStream创建的文件

    `java-deserialize-recovery`项目专注于处理使用`java.io.ObjectOutputStream`创建的文件,这是一个Java核心库中的类,用于将Java对象转换为字节流,以便进行持久存储或网络传输。在Java中,序列化是对象状态持久化...

    SimpleJava.pdf

    - **文档**:提供详尽的使用指南和API文档,帮助用户快速集成和使用。 #### 3. Java类何时以及如何被加载和初始化? - **类加载机制**:Java虚拟机采用双亲委派模型来加载类,确保了核心类库的稳定性和安全性。 - ...

    java序列化与ObjectOutputStream和ObjectInputStream的实例详解

    下面是一个简单的示例代码,演示了如何使用ObjectOutputStream和ObjectInputStream来实现序列化和反序列化: 首先,定义一个实现了Serializable接口的实体类Param: ```java public class Param implements ...

    python-javaobj:python-javaobj是一个python库,提供了读取Java对象序列化ObjectOutputStream的函数

    python-javaobj 是一个 python 库,它提供了读取和写入(写入当前是 WIP)Java 对象的函数,序列化或将被ObjectOutputStream反序列化。 这种对象表示形式是 Java 世界中的标准数据交换格式。 javaobj 模块公开了...

    java将数据写入内存,磁盘的方法

    在Java编程中,将数据写入内存和磁盘是常见的操作,这涉及到程序的数据存储和持久化。下面我们将详细介绍这两种方法。...在实际开发中,我们经常结合使用内存和磁盘,利用缓存策略来优化整体性能。

    Android使用文件进行IPC

    3. 文件大小:虽然文件可以用于IPC,但大文件可能会消耗大量内存,因此对于大量数据传输,考虑使用更高效的IPC方式,如Binder。 4. 错误处理:在序列化和反序列化过程中,需要捕获并处理可能的异常,例如`...

    java序列化和反序列化的方法

    在发送端,使用 ObjectOutputStream 将 UserMessage 对象序列化为字节流,并将其发送到网络上。在接收端,使用 ObjectInputStream 将字节流反序列化回 UserMessage 对象。 序列化和反序列化的过程中,需要注意以下...

    ObjectInputStream 和 ObjectOutputStream 介绍_动力节点Java学院整理

    然而,它也有一些潜在的风险,比如安全问题(因为序列化的数据可能包含敏感信息)和版本兼容性问题(如果对象的类结构发生变化,可能无法正确反序列化)。因此,在使用这两个类时,应充分了解它们的功能和限制,并...

    JavaEE技术问题汇总.docx

    内存泄露是程序未释放不再使用的内存,导致可用内存逐渐减少。 以上仅是部分知识点,更多如静态代理、动态代理、CGLIB与JDK代理、静态关键字、CAS单点登录原理等未展开详述。这些知识涵盖JavaEE开发的多个方面,...

    笔试Java3.doc

    5. Java 序列化:Java 序列化是指将对象转换为字节流的过程,可以使用 ObjectOutputStream 和 ObjectInputStream 实现。 6. Java 中的流:Java 中有多种类型的流,包括 InputStream、OutputStream、Reader、Writer ...

    基于java的存储与读取对象.zip

    8. **内存管理**:序列化和反序列化涉及到内存的使用,理解Java的内存模型和垃圾收集机制可以帮助优化性能和避免内存泄漏。 9. **并发编程**:如果多个线程同时读写对象,就需要考虑线程安全问题。可以使用`...

    飞鸽源代码,JAVA C++都有

    飞鸽源码会使用STL进行数据存储和处理,同时C++的动态内存管理(new/delete)也需要关注以避免内存泄漏。 4. **面向对象编程**:C++是面向对象的语言,源码中可能会包含类的设计、继承、封装和多态等概念。 5. **...

    大数据常见面试题(2019版)

    - Spark提供了一种更高效的数据处理方式,它使用内存计算,比Hadoop更快。 - Spark的主要组件包括Spark Core、Spark SQL、Spark Streaming和MLlib,了解它们的应用场景和API是基础。 7. **Java在大数据中的应用**...

Global site tag (gtag.js) - Google Analytics