質問: **■概要** Tomcat上で動作しているWebアプリが急にスローダウンする現象が発生し、原因追及に困っております。 スレッドダンプの状態などからアプリケーションのロジックそのものより、Java自体で問題が発生していないかを疑っています。 なにか原因や対策として思いつくものがありましたら教えていただけないでしょうか。 **■事象** ・LoadAverageが上昇(通常時:0.5、スローダウン時:3~5) ・CPUはuserのみが占有(IOやswapは問題なし) →ほぼTomcatが利用している ・マイナーGCも秒単位でかかるようになる(通常時:0.1ミリ秒以下、異常時:3秒前後) ・しばらくするとTomcatの再起動なしでも復旧する ・複数台のサーバでほぼ同時に発生(アクセスが集中する時間に発生するケースが多い) ・スレッドダンプを取得するとSystem.getProperty()内で呼ばれているHashtable.get()でロック待ちが多数発生 →デッドロックではない模様 **■環境情報** OS:Redhat 7.3 64bit Java:1.7.0_80 Java起動オプション: -Xms3072m -Xmx3072m -Xss800k -XX:MaxPermSize=192m -XX:+UseParallelGC -XX:+UseParallelOldGC -XX:SurvivorRatio=6 -XX:TargetSurvivorRatio=90 -XX:MaxTenuringThreshold=32 -XX:NewRatio=2 -XX:-UseCodeCacheFlushing -XX:ReservedCodeCacheSize=256m -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -XX:+PrintClassHistogram -XX:+HeapDumpOnOutOfMemoryError
回答: > > ・スレッドダンプを取得するとSystem.getProperty()内で呼ばれているHashtable.get()でロック待ちが多数発生 > > > この部分が気になりました。 Hashtable.get()はsynchronizedメソッドのため、複数スレッドからのアクセスがあった場合、 待ち合わせが発生するのは当然なのですが、待ち合わせが多数発生するほどアクセスが集中するのは、 一般的なのでしょうか?(詳しくないので疑問です。) System.getProperty()の呼び出しがTomcatで多数実行されていて、 webアプリでは実行されていないのであれば、回避しようがないのですが、 読み取り(get)しか行っていないという条件付きで、待ち合わせを回避する方法として、 ・シングルトンなクラスを作成しgetterのみ用意する。 ・または、HashMapに入れなおして保持する。 などが、可能かと思われます。 Tomcatで実行されいる気がするため、あまりいい回答ではないかと思いますが、 ご参考までに。