Java对象序列化性能提示

Java对象序列化性能提示,java,serialization,Java,Serialization,我必须将一棵巨大的对象树(7000)序列化到磁盘中。最初,我们使用Kodo将这棵树保存在数据库中,但它会进行成千上万次的查询,以将这棵树加载到内存中,这将占用本地可用时间的很大一部分 我为此尝试了序列化,实际上我得到了性能改进。然而,我觉得我可以通过编写自己的自定义序列化代码来改进这一点。我需要尽可能快地加载这个序列化对象 在我的机器中,序列化/反序列化这些对象大约需要15秒。从数据库加载它们时,大约需要40秒 考虑到对象位于树中,因此它们相互引用,有没有关于如何改进此性能的提示?您是否尝试过压

我必须将一棵巨大的对象树(7000)序列化到磁盘中。最初,我们使用Kodo将这棵树保存在数据库中,但它会进行成千上万次的查询,以将这棵树加载到内存中,这将占用本地可用时间的很大一部分

我为此尝试了序列化,实际上我得到了性能改进。然而,我觉得我可以通过编写自己的自定义序列化代码来改进这一点。我需要尽可能快地加载这个序列化对象

在我的机器中,序列化/反序列化这些对象大约需要15秒。从数据库加载它们时,大约需要40秒


考虑到对象位于树中,因此它们相互引用,有没有关于如何改进此性能的提示?

您是否尝试过压缩流(GZIPOutputStream)?

我会这样做,从我的头顶开始

系列化

  • 分别序列化每个对象
  • 为每个对象指定一个唯一的键
  • 当一个对象持有对另一个对象的引用时,将该对象的唯一键放在序列化中的对象位置。(我将使用转换为二进制的UUID)
  • 使用唯一键将每个对象保存到文件/数据库/存储器中
  • 非工业化

  • 从任意对象(通常是我怀疑的根)开始,将其取消序列化,并将其放在一个映射中,使用其唯一键作为索引,然后返回它
  • 当您在序列化流中点击一个对象键时,首先通过在映射中查找它的唯一键来检查它是否已经未序列化,如果它只是从那里抓取它,如果不是放一个延迟加载代理(对该对象重复这两个步骤)而不是真正的对象,它有钩子在需要时加载正确的对象

  • 编辑,如果有循环引用,可能需要使用两次序列化和非序列化,这会使事情变得有点复杂,但不会太复杂。

    一个优化是自定义类描述符,因此,您可以将类描述符存储在不同的数据库中,并在对象流中仅按ID引用它们。这减少了序列化数据所需的空间。例如,请参见如何在一个项目中创建类并执行它

    使类外部化而不是序列化可以提高性能。缺点是它需要大量的手工工作


    例如,还有其他序列化库,它们可以提供比Java默认序列化更好的性能。此外,如果对象图不包含循环,那么可以将其序列化得更快一些,因为序列化程序不需要跟踪它看到的对象(请参阅中的“它是如何工作的”)。

    为了提高性能,我建议根本不要使用java.io序列化。相反,你自己开始着手处理字节

    如果要对树进行java.io序列化,您可能需要确保递归不会变得太深,可以通过展平(如
    TreeSet
    所做的)或安排首先序列化最深的节点(这样您就有了反向引用,而不是嵌套的
    readObject
    调用)


    如果Kodo中没有一种方法可以一次(或几次)读取整个树,我会感到惊讶。

    不要忘记对不需要序列化的实例变量使用“transient”关键字。这将提高性能,因为您不再读取/写入不必要的数据。

    我建议您实现自定义writeObject()和readObject()方法。 通过这种方式,您将能够删除树中每个节点的写入子节点。使用默认序列化时,每个节点都将与其所有子节点一起序列化

    例如,树类的writeObject()应该遍历树的所有节点,并且只使用一些标识树级别的标记写入节点数据(没有节点本身)


    您可以查看LinkedList,了解这些方法是如何在那里实现的。它使用相同的方法来防止为每个条目写入上一个和下一个条目。

    要避免编写自己的序列化代码,请尝试一下。根据他们的网站:

    协议缓冲区是Google用于序列化结构化数据的语言中立、平台中立、可扩展的机制——比如XML,但更小、更快、更简单。您定义了如何希望将数据结构化一次,然后可以使用特殊生成的源代码来轻松地编写和读取各种数据流和使用各种语言——java、C++或Python < /P>来编写结构化数据。
    我没有用过它,但听到了很多关于它的积极的事情。另外,我必须维护一些自定义序列化代码,而且这可能是一个绝对的噩梦(更不用说跟踪bug了),所以让别人帮你做这件事总是一件好事。

    另外,看看,用于将对象序列化为XML并再次序列化的库。

    您可以使用它生成bean,Java的标准序列化性能将得到10-1000倍的提升。除非大小达到GB以上,否则很可能会远远低于1秒。

    这可能行得通,但需要重新编写我拥有的相当多的代码。这与标准序列化相比有何改进?据我所知,默认机制已经完成了。@saua因为你可以在需要时惰性地加载和实例化每个对象,而不是一次加载所有对象,你还可以自己降低字节级别并优化序列化格式。我需要提高加载和存储的性能,但我没有在问题中详细说明,实际上,空间也是一个“性能”指标。只有在序列化过程是磁盘绑定的情况下,更少的空间意味着更少的磁盘访问意味着更少的时间。它似乎不在我的系统中;它似乎受到cpu的限制,所以