Java Kryo:identityObjectMap.clear()会产生巨大的CPU负载

Java Kryo:identityObjectMap.clear()会产生巨大的CPU负载,java,performance,serialization,concurrency,kryo,Java,Performance,Serialization,Concurrency,Kryo,我需要用Kryo序列化应用程序中的许多对象。其中一些是真正的大对象图,其他的只是带有一些基本体的小容器(但是有很多这样的容器)。这些序列化过程可以在多个线程中同时发生(在不同的数据元素上) 根据文件: Kryo实例不是线程安全的 创建一个新的Kryo实例非常昂贵 我的逻辑结论是拥有一个ThreadLocal,它充当初始化Kryo实例的缓存 但是,JVisualVM现在告诉我,方法com.esotericsoftware.kryo.util.identityObjectMap.clear()消耗了

我需要用Kryo序列化应用程序中的许多对象。其中一些是真正的大对象图,其他的只是带有一些基本体的小容器(但是有很多这样的容器)。这些序列化过程可以在多个线程中同时发生(在不同的数据元素上)

根据文件:

  • Kryo
    实例不是线程安全的
  • 创建一个新的
    Kryo
    实例非常昂贵
  • 我的逻辑结论是拥有一个
    ThreadLocal
    ,它充当初始化
    Kryo
    实例的缓存

    但是,JVisualVM现在告诉我,方法
    com.esotericsoftware.kryo.util.identityObjectMap.clear()
    消耗了应用程序90%的CPU时间(自时间)。对我来说,这看起来好像Kryo需要在序列化过程之间以某种方式“重置”自己,显然这个操作相当昂贵


    有没有人知道这里可能发生了什么,以及为什么这个操作会使我的应用程序性能下降这么多,或者我如何能比使用
    Kryo
    实例的线程本地弱引用缓存做得更好?

    你应该使用一个Kryo实例池,并在每次将实例释放到池时重置实例

    现在在Kryo中有一个正式的池实现,请参阅(自v3 afaik起),或其他实现此策略的项目。

    您可以使用
    Kryo\setReference(false)

    与:

    Kryo跟踪读/写对象。 在内部,Kryo使用
    identityobjectmap
    管理读/写对象

    Kryo#setReference(false)
    
    将停止跟踪读/写对象,因此不再调用
    identityobjectmap#clear

    Kryo#setReference(false)