java - java序列化过程中可以缓冲对象吗?

标签 java serialization

我有一个非常大的对象,我希望对其进行序列化。在序列化过程中,它作为 weblogic.utils.io.UnsyncByteArrayOutputStream 占用了大约 130MB 的堆。我正在使用 BufferedOutputStream 来加快将数据写入磁盘的速度,从而减少了该对象在内存中的保存时间。

是否可以使用缓冲区来减小内存中对象的大小?如果有一种方法可以一次将它序列化 x 个字节并将这些字节写入磁盘,那就太好了。

示例代码如下,如果它有任何用处的话。尽管我认为没有什么可继续的。如果需要序列化对象的完整内存副本(因此没有序列化缓冲区的概念),那么我想我被卡住了。

    ObjectOutputStream tmpSerFileObjectStream = null;
    OutputStream tmpSerFileStream = null;
    BufferedOutputStream bufferedStream = null;
    try {

        tmpSerFileStream = new FileOutputStream(tmpSerFile);
        bufferedStream = new BufferedOutputStream(tmpSerFileStream);

        tmpSerFileObjectStream = new ObjectOutputStream(bufferedStream);
        tmpSerFileObjectStream.writeObject(siteGroup);
        tmpSerFileObjectStream.flush();

    } catch (InvalidClassException invalidClassEx) {
        throw new SiteGroupRepositoryException(
                "Problem encountered with class being serialised", invalidClassEx);
    } catch (NotSerializableException notSerializableEx) {
        throw new SiteGroupRepositoryException(
                "Object to be serialized does not implement " + Serializable.class,
                notSerializableEx);
    } catch (IOException ioEx) {
        throw new SiteGroupRepositoryException(
                "Problem encountered while writing ser file", ioEx);
    } catch (Exception ex) {
        throw new SiteGroupRepositoryException(
                "Unexpected exception encountered while writing ser file", ex);
    } finally {
        if (tmpSerFileObjectStream != null) {
            try {
                tmpSerFileObjectStream.close();
                if(null!=tmpSerFileStream)tmpSerFileStream.close();
                if(null!=bufferedStream)bufferedStream.close();
            } catch (IOException ioEx) {
                logger.warn("Exception caught on trying to close ser file stream", ioEx);
            }
        }
    }

最佳答案

这在很多层面上都是错误的。这是对序列化的大规模滥用。序列化主要用于临时存储对象。例如,

  1. tomcat 服务器重启之间的 session 对象。
  2. 在 jvms 之间传输对象(网站负载平衡)

Java 的序列化没有努力处理对象的长期存储(不支持版本控制)并且可能无法很好地处理大对象。

对于这么大的事情,我建议先进行一些调查:

  1. 确保您没有尝试保留整个 JVM 堆。
  2. 寻找可以标记为“ transient ”的成员变量以避免将它们包含在序列化中(也许您有对服务对象的引用)
  3. 考虑存在内存泄漏和对象过大的可能性。

如果一切确实正确,您将不得不研究 java.io.Serialization 的替代方案。通过 java.io.Externalization 进行更多控制可能会奏效。但我建议使用 json 或 xml 表示形式。

更新:

调查:

  1. google's protocol buffer
  2. facebook's Thrift
  3. Avro
  4. Cisco's Etch

Take a look at this benchmarkings as well.

关于java - java序列化过程中可以缓冲对象吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3156705/

相关文章:

c# - XML 序列化和继承类型

qt - 如何可视化来自谷歌 Protocol Buffer 的数据?

java - 我需要获取一个字符串并输出该字符串中出现次数最多的单词

java - 在每个事务中查询\更新数据库是否有效 : Java Application

java - Eclipse无法正常运行

java - 如何序列化/反序列化java中的对象列表?

java - FileOutputStream 写入的内容少于应有的内容

java - Selenium - Maven/TestNG : how can we add testng parameters in Java class while adding "main method" to create executable/runnable. jar 文件?

java - 如何通过 JMS 发送 Kryo 序列化对象?

python - Django Rest Framework 返回字典而不是 OrderedDicts