[Seasar-user:15750] s2-extension:HashMap の無限回廊
Shinichi_TAKEUCHI
[E-MAIL ADDRESS DELETED]
2008年 9月 12日 (金) 21:02:36 JST
お世話になります、工楽房の竹内と申します。
以下のような状況で、無限ループになる場合があります。
場所は、次のメソッドです。
org.seasar.extension.dxo.converter.impl.ConverterFactoryImpl.getConverter(ConverterFactoryImpl.java:106)
■状況
1)マルチコアマシン、マルチスレッドOS(JVM)
Solaris10-Sparc:32Core-CPUs / 64bitJVM
2)高負荷での多重処理
MultiThread で 300TPS 程度
■現象
1)突然CPUが100%近くになる
2)ThreadDumpするとBlockされているものがない
9つのThreadが java.util.HashMap.get にて実行中(RUNNABLE)
■考察
調査してみると、[参考1]のような@ITの記事がみつかりました。
概要としては、NormalなHashMapはMultiThread環境において、内部のLinkedList状のデータがLoopしてしまい、get()などが無限ループになることがあるようです。
[参考1]:http://www.atmarkit.co.jp/fjava/rensai4/troublehacks10/troublehacks10_1.html
■考えられる対策
DXOは、そもそもAutoDeployなどではSingleton指定であり、MultiThreadで使用されることが前提であることから以下のような対策が考えられます。
いかがでしょうか?
1)ConcurrentMap を使用する
Java1.5以上に限定されます
2)問題となるメソッドまたはその一部をSynchronized指定
getConverter() , detectConverter()
3)SyncronzedMapでWrapする
protected Map converterCache = Collections.synchronizedMap(new HashMap());
----------------------------------------------------------------
スレッドダンプの一部(ほぼ同じThreadが9つある)
----------------------------------------------------------------
"p: thread-pool-1; w: 32" daemon prio=3 tid=0x000000010369fc00 nid=0xe5 runnable [0xffffffff6fff9000..0xffffffff6ffff6c0]
java.lang.Thread.State: RUNNABLE
at java.util.HashMap.get(HashMap.java:303)
at org.seasar.extension.dxo.converter.impl.ConverterFactoryImpl.getConverter(ConverterFactoryImpl.java:106)
at org.seasar.extension.dxo.command.impl.BeanToBeanDxoCommand.convertScalar(BeanToBeanDxoCommand.java:60)
at org.seasar.extension.dxo.command.impl.AbstractDxoCommand$ListToListConvertsionHelper.convert(AbstractDxoCommand.java:286)
at org.seasar.extension.dxo.command.impl.AbstractDxoCommand.execute(AbstractDxoCommand.java:78)
at org.seasar.extension.dxo.DxoInterceptor.invoke(DxoInterceptor.java:57)
Seasar-user メーリングリストの案内