场景,线上堆栈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
相关推荐
在Java编程中,Socket和ObjectOutputStream是两个非常重要的概念,它们是进行网络通信的基础。Socket是TCP/IP协议的实现,提供了两台计算机之间双向、独立的数据传输通道。而ObjectOutputStream则是一个序列化流,...
- **内存泄漏检测**:使用内存分析工具,如VisualVM、MAT(Memory Analyzer Tool)等,找出程序中的内存泄漏问题。 4. **垃圾收集机制** Java的垃圾收集器负责自动回收不再使用的对象所占用的内存。了解并优化...
- **ObjectOutputStream**:如果序列化处理不当,可能导致内存消耗过大。 5. **解决方案**: - **生成dump文件**:使用wsadmin脚本客户端的generateHeapDump操作。 - **并发读取配置文件**:确保CAS并发读取配置...
内存泄露是常见的问题,当不再使用的对象仍然被引用,无法被垃圾收集器回收。此外,栈内存用于存储方法局部变量,随着方法的调用和返回自动管理。 四、基础Java学习 学习Java的基础涉及语法、控制结构、异常处理、...
要序列化一个对象,你需要实现Serializable接口,然后使用ObjectOutputStream的writeObject()方法: ```java try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("serialized_object.ser...
真正的内存泄漏可能发生在不再使用的对象引用被意外保持,导致GC无法回收这些对象占用的内存。 Java中的多态性体现在方法的重写(Overriding)和重载(Overloading)。重写是指子类可以提供与父类相同签名的方法,但...
处理大字段时需要特别注意内存管理,因为它们可能导致内存溢出(Out Of Memory)问题,影响应用的性能和稳定性。这篇博客文章可能详细探讨了如何在Java中有效地处理大字段,以及可能遇到的相关挑战。 1. **大字段...
`java-deserialize-recovery`项目专注于处理使用`java.io.ObjectOutputStream`创建的文件,这是一个Java核心库中的类,用于将Java对象转换为字节流,以便进行持久存储或网络传输。在Java中,序列化是对象状态持久化...
- **文档**:提供详尽的使用指南和API文档,帮助用户快速集成和使用。 #### 3. Java类何时以及如何被加载和初始化? - **类加载机制**:Java虚拟机采用双亲委派模型来加载类,确保了核心类库的稳定性和安全性。 - ...
下面是一个简单的示例代码,演示了如何使用ObjectOutputStream和ObjectInputStream来实现序列化和反序列化: 首先,定义一个实现了Serializable接口的实体类Param: ```java public class Param implements ...
python-javaobj 是一个 python 库,它提供了读取和写入(写入当前是 WIP)Java 对象的函数,序列化或将被ObjectOutputStream反序列化。 这种对象表示形式是 Java 世界中的标准数据交换格式。 javaobj 模块公开了...
在Java编程中,将数据写入内存和磁盘是常见的操作,这涉及到程序的数据存储和持久化。下面我们将详细介绍这两种方法。...在实际开发中,我们经常结合使用内存和磁盘,利用缓存策略来优化整体性能。
3. 文件大小:虽然文件可以用于IPC,但大文件可能会消耗大量内存,因此对于大量数据传输,考虑使用更高效的IPC方式,如Binder。 4. 错误处理:在序列化和反序列化过程中,需要捕获并处理可能的异常,例如`...
在发送端,使用 ObjectOutputStream 将 UserMessage 对象序列化为字节流,并将其发送到网络上。在接收端,使用 ObjectInputStream 将字节流反序列化回 UserMessage 对象。 序列化和反序列化的过程中,需要注意以下...
然而,它也有一些潜在的风险,比如安全问题(因为序列化的数据可能包含敏感信息)和版本兼容性问题(如果对象的类结构发生变化,可能无法正确反序列化)。因此,在使用这两个类时,应充分了解它们的功能和限制,并...
内存泄露是程序未释放不再使用的内存,导致可用内存逐渐减少。 以上仅是部分知识点,更多如静态代理、动态代理、CGLIB与JDK代理、静态关键字、CAS单点登录原理等未展开详述。这些知识涵盖JavaEE开发的多个方面,...
5. Java 序列化:Java 序列化是指将对象转换为字节流的过程,可以使用 ObjectOutputStream 和 ObjectInputStream 实现。 6. Java 中的流:Java 中有多种类型的流,包括 InputStream、OutputStream、Reader、Writer ...
8. **内存管理**:序列化和反序列化涉及到内存的使用,理解Java的内存模型和垃圾收集机制可以帮助优化性能和避免内存泄漏。 9. **并发编程**:如果多个线程同时读写对象,就需要考虑线程安全问题。可以使用`...
飞鸽源码会使用STL进行数据存储和处理,同时C++的动态内存管理(new/delete)也需要关注以避免内存泄漏。 4. **面向对象编程**:C++是面向对象的语言,源码中可能会包含类的设计、继承、封装和多态等概念。 5. **...
- Spark提供了一种更高效的数据处理方式,它使用内存计算,比Hadoop更快。 - Spark的主要组件包括Spark Core、Spark SQL、Spark Streaming和MLlib,了解它们的应用场景和API是基础。 7. **Java在大数据中的应用**...