2016-04-13 7 views
1

私のアプリケーションでは、Kryoで多くのオブジェクトを直列化する必要があります。それらのうちのいくつかは本当に大きなオブジェクトグラフであり、その他はいくつかのプリミティブを持つ小さなコンテナです(しかし、これらのコンテナのがです)。これらのシリアライゼーションプロセスは、複数のスレッドで(異なるデータ要素上で)同時に発生する可能性があります。Kryo:IdentityObjectIntMap.clear()は非常に大きなCPU負荷を発生します

ドキュメントによると:

  1. Kryoインスタンスはスレッドセーフではありません。
  2. 新しいKryoインスタンスを作成するには高価です。

私にとって論理的な結論は、Kryoインスタンスのキャッシュとして機能するThreadLocal<WeakReference<Kryo>>を持つことでした。

しかし、JVisualVMでは、com.esotericsoftware.kryo.util.IdentityObjectIntMap.clear()というメソッドがアプリケーションのCPU時間(自己時間)の90%を消費していることがわかりました。私にとって、これは、Kryoがシリアル化プロセスの間に何らかの形で「リセット」する必要があるかのように見えます。明らかに、この操作はかなり高価です。

ここで何が起こっているのか、そしてなぜこの操作でアプリケーションのパフォーマンスが低下するのか、あるいはKryoインスタンスのスレッドローカル弱参照キャッシュよりもうまくいくのかどうかは誰にも分かりませんか?

答えて

0

Kryoインスタンスのプールを使用し、インスタンスをプールに解放するたびにインスタンスをリセットする必要があります。

Kryoには公式プールの実装があります(KryoPool(v3 afaik以降))、またはこの戦略を実装する他のプロジェクトがあります。

0

Kryo#setReference(false)を使用できます。

付:

Kryo#setReference(true) 

Kryoトラック/書き込みオブジェクトをお読みください。 内部的には、KryoはIdentityObjectIntMapを使用して読み取り/書き込みオブジェクトを管理します。

Kryo#setReference(false) 

は、読み取り/書き込みオブジェクトの追跡を停止するため、IdentityObjectIntMap#clearはもはや呼び出されません。

関連する問題