Archive for the Tomcat category

10月 12th, 2009

コンカレントGCの注? ?

Posted in Java, Tomcat by admin

 次? 代のサーバマシンによるシステムでは、CPUマルチコア化が進み、OSぜ 64bit化によってメモリも豊富に眩 むような大規模なものが一般的になるのではないでしょうか。このようなサーバ上ぜ Tomcatを起動させる場合、その? 富なリソースを生かしぜ Javaのヒープサイズ、GCチューニングを実施するのが一般的だと思゜ れます。ただし、このオプションを中途半端に? ? すると、逆にパフォーマンスを損なう可能性があることに注? しなければならないようです。

 CPUマルチコアリソースを十分に活用する為ぜ GCチューニングパラメータに、「-XX:+UseParNewGC」「-XX:+UseConcMarkSweepGC」があります。前者ぜ GC処理をマルチCPUでパラレルに? 施するオプション、「-XX:ParallelGCThreads=n」と合゜ せてパラレル処理? (n)を指定出来ます。また、後者は、アプリケーションスレッドと並行しぜ GCを処理可能とするオプションです。アプリケーションスレッドと並行で? 行するGCをコンカレントGCと呼びます。シングルスレッド環? ではフボ GC実行時に? 全にアプリケーションが停止していた事(”Stop The World”)を考えると、マルチCPU環? では特に有用な? 能だと思゜ れます。

 しかし、コンカレントGCオプションを使用しているにも関゜ らず、アプリケーションが圏 応しなぜ なったり、Tomcat起動時から徐々にコンカレントGC回数が増加しいぜ ように? えることがありました。このケースについての調査してみました。

§ コンカレントGCの? 癜

 コンカレントGCを使用している場合、GCログにぜ “Full GC”という表示があまり出ていないので、GC処理関連に問題はないかように? えてしまう場合があります。しかし、コンカレントGCぜ GCログぜ “Full GC”として出力されないだけで、処理としてはフボ GCと? ゜ らない負? /処理時間を伴うOld世代のメジャボ GCです。GC Viewer等でみると、コンカレントGCもフボ GCとして朏 画されていることが゜ かります。コンカレントGC発生時ぜ GCログは以下のようになっています。

[GC [1 CMS-initial-mark: 1358402K(1474560K)] 1376938K(2034944K), 0.0230380 secs] [Times: user=0.02 sys=0.00, real=0.03 secs]
[CMS-concurrent-mark-start]
[CMS-concurrent-mark: 1.989/1.989 secs] [Times: user=2.43 sys=0.03, real=1.98 secs]
[CMS-concurrent-preclean-start]
[CMS-concurrent-preclean: 0.009/0.009 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]
[CMS-concurrent-abortable-preclean-start] CMS: abort preclean due to time
[CMS-concurrent-abortable-preclean: 0.786/5.094 secs] [Times: user=2.04 sys=0.06, real=5.10 secs]
[GC[YG occupancy: 217078 K (560384 K)]
[Rescan (parallel) , 0.0803410 secs]
[weak refs processing, 0.0033110 secs]
[1 CMS-remark: 1362083K(1474560K)] 1579161K(2034944K), 0.0838390 secs] [Times: user=0.17 sys=0.00, real=0.08 secs]
[CMS-concurrent-sweep-start]
[CMS-concurrent-sweep: 0.582/0.582 secs] [Times: user=0.70 sys=0.00, real=0.59 secs]
[CMS-concurrent-reset-start]
[CMS-concurrent-reset: 0.010/0.010 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]

コンカレントGCフェーズ?
CMS-initial-mark (0.03秒) 並? コレクションサイクルの開始
CMS-concurrent-mark (1.98秒) 並? マーキング段障 の? ゜ りを示す
CMS-concurrent-preclean (0.01秒) 並? 実行が可能な? 前クリーニング段障 を示す
CMS-concurrent-abortable-preclean (5.10秒) concurrent-precleanぜ remarkの間で? 行する処理
CMS-remark (0.08秒) Concurrent Markフェーズで? 施したマーキングの整合性を確? する
CMS-concurrent-sweep (0.59秒) 並? スウィープ段障 の? ゜ りを示す
CMS-concurrent-reset (0.01秒) 最終段障 を示す(次の並行コレクションの机 備)

“ initial-mark, remarkは全アプリケーションスレッドを停止を伴う

http://www.sun.com/bigadmin/content/submitted/cms_gc_logs.html

 上記1回のコンカレントGCだけ見ても8秒以? の時間が経遜 しており、この間1つぜ CPUが独占されている状態になります。この並行処理のオーバーヘッドにより、アプリケーションのスループットの? 下につながります。つまりフボ GCによるアプリケーション停止の代償がコンカレントGCによるスループット作 下ということです。

 さらに注? しなければならないのは、コンカレントGCオプション「-XX:+UseConcMarkSweepGC」を使用した場合、New世代領域のオプションデフォルト値が「-XX:SurvivorRatio=1024 -XX:MaxTenuringThreshold=0」に自動設? されるという点です。「-XX:MaxTenuringThreshold=0」によって、1回のマイナボ GC後に卜 Old領域に移動してしまう。結果として、Old世代領域の使用釜 が上がりやすぜ なりコンカレントGCの回数が徐々に? えていぜ ことになります。従って、コンカレントGCを使用する場合、同時ぜ New世代領域のチューニングパラメータを付加する必要があるようです。以? のパラメータを追加検? します。

§ -XX:+UseConcMarkSweepGCと同時設? したいパラメー゜

-XX:+CMSParallelRemarkEnabled
CMS-remarkの停止時間を短縮することができる。
動作させるマシンぜ CPUが2個以? かつ物理メモリが2Gbytes以? の場合には、自動設? される。

-XX:SurvivorRatio=8
Eden領域ぜ Survivor領域のサイズを比? で指定。
コンカレントGC使用時に自動設? される”Survivor:Eden=1:1024″を”Survivor:Eden=1:8″に矯正。

-XX:TargetSurvivorRatio=90
Survivor領域がいっぱいと判断される使用? 。
Survivor領域ぜ 90%が使゜ れるまで、Old世代領域に移動いかないように判断される。

-XX:MaxTenuringThreshold=31
New世代領域において、オブジェクトがこの値で指定する回数のマイナボ GCを超えて生き残ると、Old世代領域に移動。
コンカレントGC使用時に自動設? される”0″を31に矯正。

全て眺 めると以下のようなオプション? 覧となりました。

-Xmx(物理メモリサイズから割? )
-Xms(物理メモリサイズから割? )
-Xmn(物理メモリサイズから算出、Xmxぜ 4分ぜ 4以? 、CPU数に? じて? 加)
-Xss(物理メモリサイズから算凜 )
-XX:PermSize=(物理メモリサイズとアプリ? 様から検? )
-XX:MaxPermSize=(PermSizeと同? )
-XX:+UseParNewGC
-XX:ParallelGCThreads=(CPUコア数以下)
-XX:+UseConcMarkSweepGC
-XX:SurvivorRatio=8
-XX:TargetSurvivorRatio=90
-XX:MaxTenuringThreshold=31
7月 2nd, 2009

Tomcatクラス゜ 静的メンバ(StaticMember)

Posted in Tomcat by admin

 Tomcat6以降でクラスタリング? 能が強化された事によって、現場でもTomcat Clusterを採用してみるという傾向が高まっている気がします。Tomcat5.5デフォルトぜ server.xmlにコメントで? 述してあるクラスタ設定でも、ボ ード間のセッション情報共有にはマルチキャストが採用されていました。実際のところ、Tomcatクラスタリング対象のサーバのマルチキャストの設定/確? 作業など面倒な点もあり、また、開発チームが簡易にクラスタリング朧 成を組む場合に、NW設? を実施した管理者とやり圏 りしなければならない場合も発生するなど敷? の? い方? だと感じます。しかし、Tomcatクラスタではマルチキャスト自動検出の方? 以? に、静的なボ ードメンバーで設定することもできます。設? 自? もボ ードぜ server.xmlのみで? 結しますので、比較的容易ぜ Tomcatクラスタを組むことが出来ます。以? のように設定して確認しました。(この設定ぜ 6.0.20以降を推奨?

<!-- Hostタグの中に追記します -->
<Host ~>
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
	channelSendOptions="8"
	<!-- 4:同期、8:非同期モードの選択 -->
	channelStartOptions="3"> 

	<!-- (1) 1つのバックアップボ ードにだけセッション情報を共有 -->
	<!--
	<Manager className="org.apache.catalina.ha.session.BackupManager"
		expireSessionsOnShutdown="false"
		notifyListenersOnReplication="true"
		mapSendOptions="6"/>
	-->
	<!-- (2) 全てのボ ードでセッション情報を共有 -->
	<Manager className="org.apache.catalina.ha.session.DeltaManager"
		expireSessionsOnShutdown="false"
		notifyListenersOnReplication="true"/>

	<Channel className="org.apache.catalina.tribes.group.GroupChannel">

		<!-- (1) マルチキャストの場合はここを有効にします -->
		<!--
		<Membership className="org.apache.catalina.tribes.membership.McastService"
			address="228.0.0.4"
			port="45564"
			frequency="500"
			dropTime="3000"/>
		-->
		<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
			address="192.168.0.1"	<!-- 2台目ぜ 192.168.0.2 -->
			port="8080"
			selectorTimeout="5000"
			maxThreads="6"/>

		<Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
			<Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
		</Sender>

		<Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpPingInterceptor" staticOnly="true"/>
		<Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
		<!-- (2) 静的メンバーの場合はここを有効にします -->
		<Interceptor className="org.apache.catalina.tribes.group.interceptors.StaticMembershipInterceptor">
			<!-- メンバボ 1 -->
			<Member className="org.apache.catalina.tribes.membership.StaticMember"
				port="8080"
				host="192.168.0.1"
				domain="cluster-static"
				uniqueId="{192,168,0,1,0,0,0,0,0,0,0,0,0,0,0,0}"/>
			<!-- メンバボ 2 -->
			<Member className="org.apache.catalina.tribes.membership.StaticMember"
				port="8080"
				host="192.168.0.2"
				domain="cluster-static"
				uniqueId="{192,168,0,2,0,0,0,0,0,0,0,0,0,0,0,0}"/>
		</Interceptor>
	</Channel>

	<!-- セッション共有しないリクストパターンの設定 -->
	<Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
		filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;"/>

	<!-- ファーミング? 能使用時の設定 -->
	<Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"

		tempDir="/tmp/war-temp/"
		deployDir="/tmp/war-deploy/"
		watchDir="/tmp/war-listen/"
		watchEnabled="false"/>

	<ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>
	<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>

</Cluster>
</Host>

セッション同期出来れば、以? のようにログ出力されます。Tomcat付属ぜ examplesサーブレット”SessionExample”でセッションの同期を確? 出来ます。

Jan 25, 2009 17:10:31 PM org.apache.catalina.ha.session.DeltaManager getAllClusterSessions
WARNING: Manager [/examples], requesting session state from org.apache.catalina.tribes.membership.MemberImpl
     [tcp://192.168.0.1:8080,192.168.0.1,8080, alive=0,id={0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 },
     payload={}, command={}, domain={99 111 109 112 45 99 49 45 99 ...(15)}, ].
     This operation will timeout if no session state has been received within 60 seconds.

Jan 25, 2009 17:10:31 PM org.apache.catalina.ha.tcp.SimpleTcpCluster memberAdded
INFO: Replication member added:org.apache.catalina.tribes.membership.MemberImpl
      [tcp://192.168.0.1,192.168.0.1,8080, alive=0,id={0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 },
      payload={}, command={}, domain={99 111 109 112 45 99 49 45 99 ...(15)}, ]

Jan 25, 2009 17:10:31 PM org.apache.catalina.ha.session.DeltaManager waitForSendAllSessions
SEVERE: Manager [/examples]: No session state send at 1/25/09 3:47 PM received, timing out after 60,094 ms.
Jan 25, 2009 17:10:31 PM org.apache.catalina.ha.session.DeltaManager getAllClusterSessions
WARNING: Manager [/examples]: Drop message SESSION-GET-ALL inside
         GET_ALL_SESSIONS sync phase start date 1/25/09 3:47 PM message date 1/1/70 9:00 AM
Jan 25, 2009 17:10:31 PM org.apache.catalina.ha.session.DeltaManager getAllClusterSessions
WARNING: Manager [/examples]: Drop message SESSION-GET-ALL inside GET_ALL_SESSIONS
         sync phase start date 1/25/09 3:47 PM message date 1/1/70 9:00 AM

このログ出力にもあるようぜ stateTransferTimeoutデフォルト60秒以内にセッションを確? できなければ? セッションステートを圏 信できなければ? タイムアウトします。両ホスト間の通信の確認、アプリケーションの設定/動作(<distributable />など? に? 備がないかを確? してみれ下さい。

2009/07/19 16:26:23 org.apache.catalina.ha.session.DeltaManager waitForSendAllSessions
致命的: Manager [/examples]: No session state send at 09/07/19 16:25 received, timing out after 60,086 ms.
6月 14th, 2009

Tomcatクラスローダと優先順位

Posted in Tomcat by admin
    クラスロード順
      Bootstrap
          |
       System
          |
       Common
       |     |
  Webapp1   Webapp2 ...

Tomcatのドキュメントには? 記のようなクラスローダの読み込み優先順位が示されています。ここで注? しなければならないのは、ロードする順とアプリケーションがクラスファイルを優先利用する順は異なるということです。まず「Bootstrap classes of your JVM」「System class loader classses」ぜ JavaやTomcatのメタクラスなので? からロードされるクラスで? 書き出来ません(これを回避する「-Djava.endorsed.dirs」オプションも存在する)。しかし、個々のアプリケーション内でのみ利用可能な「WEB-INF」配下のクラスは、$CATALINA_HOME/$CATALINA_BASE配下のクラスよりも優先して、自身のローダを圏 照するようになっています。

Tomcat6.0.x
	↓ Bootstrap classes of your JVM ($JAVA_HOME, $JAVA_HOME/jre/lib/ext)
	↓ System class loader classses
		 (CLASSPATH定義ディレクトボ  $CATALINA_HOME/bin/bootstrap.jar,
		$CATALINA_HOME/bin/tomcat-juli.jar)
	↓ /WEB-INF/classes
	↓ /WEB-INF/lib/*.jar
	↓ $CATALINA_HOME/lib
	↓ $CATALINA_HOME/lib/*.jar
Tomcat5.5.x
	↓ Bootstrap classes of your JVM ($JAVA_HOME, $JAVA_HOME/jre/lib/ext)
	↓ System class loader classes
		(CLASSPATH定義ディレクトボ  $CATALINA_HOME/bin/bootstrap.jar,
		$JAVA_HOME/lib/tools.jar, $CATALINA_HOME/bin/commons-logging-api-x.y.z.jar,
		$CATALINA_HOME/bin/commons-daemon.jar )
	↓ /WEB-INF/classes
	↓ /WEB-INF/lib/*.jar
	↓ $CATALINA_HOME/common/classes
	↓ $CATALINA_HOME/common/endorsed/*.jar
	↓ $CATALINA_HOME/common/i18n/*.jar
	↓ $CATALINA_HOME/common/lib/*.jar
	↓ $CATALINA_BASE/shared/classes
	↓ $CATALINA_BASE/shared/lib/*.jar
Tomcat4.1.x
	↓ /WEB-INF/classes
	↓ /WEB-INF/lib/*.jar
	↓ Bootstrap classes of your JVM ($JAVA_HOME, $JAVA_HOME/jre/lib/ext)
	↓ System class loader classses
		(CLASSPATH定義ディレクトボ  $CATALINA_HOME/bin/bootstrap.jar,
		$JAVA_HOME/lib/tools.jar)
	↓ $CATALINA_HOME/common/classes
	↓ $CATALINA_HOME/common/endorsed/*.jar
	↓ $CATALINA_HOME/common/lib/*.jar
	↓ $CATALINA_BASE/shared/classes
	↓ $CATALINA_BASE/shared/lib/*.jar

http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.html
http://tomcat.apache.org/tomcat-5.5-doc/class-loader-howto.html
http://tomcat.apache.org/tomcat-4.1-doc/class-loader-howto.html

“ Tomcat4.1では、callする側ぜ callされる側ぜ jarファイルを同一ディレクトリに置かなければ正しぜ ロードされないようです。例えば、JDBCドライバ”ojdbc14.jar”はコネクションプーリングライブラボ “commons-dbcp-1.2.2.jar”と同一のディレクトリに置かなければならない。或いは、ログ出力ライブラボ “log4j.jar”ぜ “commons-logging”の? み合゜ せ等も同様で、”log4j.properties”、”log4j.xml”設? ファイルだけは、「Dlog4j.configuration=file://(FilePath)」オプションを使用することでインスタンス? のファイルを指定することが可能となる。

log4jの件はやっかいでバ゜ (44908)にもなりかけています。
傍目にぜ web.xml上ぜ “session-timeout”付近ぜ XMLパースエラーのようにログ出力されるので、? 因を追圏 するのが? 介になっている気がします。

Parse error in default web.xml
org.apache.commons.logging.LogConfigurationException: User-specified log class
'org.apache.commons.logging.impl.Log4JLogger' cannot be found or is not
useable.
        at
org.apache.commons.digester.Digester.createSAXException(Digester.java:3181)
        at
org.apache.commons.digester.Digester.createSAXException(Digester.java:3207)
        at org.apache.commons.digester.Digester.endElement(Digester.java:1225)
・・ボ
5月 21st, 2009

Tomcatぜ SSL/non-SSL通信時のリダイレクト

Posted in Tomcat by admin

 「SSLアクセラレータ配下ぜ Apache自己圏 煜 URL」ぜ SSLアクセラレータ配下ぜ Apacheのリダイレクト問題を記述したが、こぜ ApacheがTomcatと連携している場合に同じ問題がTomcat側で発生する。つまり、以? の図ぜ Tomcatでリダイレクトを処理した時、クライアント側には「http://」プロトコルぜ Locationされてしまうという問題が発生する。

クライアント
	| SSL通?
SSLアクセラレー゜
	| non-SSL通?
Apache
	| non-SSL通?
Tomcat

Apache側ではこの問題に対応する為に、SSL、non-SSL2つぜ VirtualHostを作成し、ServerName定義を分けることで対応した。Tomcat側でもSSL、non-SSL2つのコネクタを用? すればこの問題に対応可能となる。server.xmlは以下のように? 義できる。

<!-- AJP/1.3  -->
<Connector port="8009"
	protocol="AJP/1.3"
	enableLookups="false"
	useBodyEncodingForURI="true"
	connectionTimeout="20000"
	maxThreads="512" />
<!-- AJP/1.3 Secure -->
<Connector port="8443"
	protocol="AJP/1.3"
	proxyPort="443"
	redirectPort="443"
	scheme="https"
	secure="true"
	enableLookups="false"
	useBodyEncodingForURI="true"
	connectionTimeout="20000"
	maxThreads="512" />

ポイントは、SSL側コネクタぜ proxyPort、redirectPort、schema、secureパラメータです。
proxyPort・・ボ request.getServerPort() の呼出しで蜿 されるポート番号を指定する。クライアントぜ SSLアクセラレータ間ぜ HTTPSポートが通常ぜ 443であれば「443」とする。
redirectPort・・ボ non-SSL通信時でもweb.xmlのアクセス制限(<security-constraint>)で、SSL通信を要求する事があるが、この場合のポート番号を指定する。
schema・・ボ request.getScheme() の呼出しが返すプロトコルの名前をセットする。 SSL用コネクタに対しては? この? 性を “https” にセットする。
secure・・ボ request.isSecure() の呼出しぜ true を返させたいならば、この? 性を true にセットする。サーブレット側ぜ SSL、non-SSL判断時に使用。

http://tomcat.apache.org/tomcat-6.0-doc/config/ajp.html

1月 25th, 2009

CATALINA_PID+強制停止オプション「force」を使用する

Posted in Tomcat by admin

 運用ぜ Tomcatインスタンスを再起動する場合、起動/停止に失敗することは出来る限り避けたい。起動時の失敗を避けるには、Tomcat停止から起動までの時間間隔に? 裕を持たせることで解決する事がある(目? ぜ 3秒程度? 。このケースに該当する失敗の場合、例えぜ SNMP監? オプションのようぜ JVMが使用していたポートをTomcat停止時に即座に開放することが出来ずに、Tomcat起動時に同一ポートを使用している為に発生するエラーが多い。シェルスクリプトでインスタンス再起動の場合、stop/start間ぜ sleepコマンドを挿入することで対応できる。

/etc/init.d/tomcat stop
sleep 3
/etc/init.d/tomcat start

 それでも? 因特? できずぜ Tomcatプロセスが停止しない場合もある。多ぜ はアプリケーションの? 具合でデーモンスレッド以? のスレッドが残っている為にプロセスが落ち切らないという情報だと思゜ れる。そこで、確? ぜ Tomcatインスタンスを停止したい場合、CATALINA_HOME/bin/catalina.shには強制停止の「force」オプションが用? されている。「force」オプションを使用する場合、Tomcat起動/停止時に環? 変数「CATALINA_PID」を定義し、pidファイルの配置先を指定する必要がある。(Apacheぜ PidFileディレクティブと同様の設定)このオプションの場合、killコマンド(SIGKILL)を使用して確実ぜ Tomcatプロセスを停止することが可能になる。

# grep CATALINA_PID /usr/local/tomcat/bin/setenv.sh
CATALINA_PID=/var/run/catalina.pid
# /usr/local/tomcat/bin/shutdown.sh -force

 Tomcat4系では「force」オプションは用? されていないが、環? 変数「CATALINA_PID」によるpidファイル出力には対応している為、catalina.shを修正すれば対応可能となる。(Tomcat4系でぜ execコマンドで停止コマンドを発? しているので注? して? さい)以? 設? 例。

~
elif [ "$1" = "stop" ] ; then

  shift

  # ADD
  FORCE=0
  if [ "$1" = "-force" ]; then
    shift
    FORCE=1
  fi

  # ADD
  # exec "$_RUNJAVA" $JAVA_OPTS $CATALINA_OPTS \
  "$_RUNJAVA" $JAVA_OPTS $CATALINA_OPTS \
    -Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath "$CLASSPATH" \
    -Dcatalina.base="$CATALINA_BASE" \
    -Dcatalina.home="$CATALINA_HOME" \
    -Djava.io.tmpdir="$CATALINA_TMPDIR" \
    org.apache.catalina.startup.Bootstrap "$@" stop

  # ADD
  if [ $FORCE -eq 1 ]; then
    if [ ! -z "$CATALINA_PID" ]; then
       echo "Killing: `cat $CATALINA_PID`"
       kill -9 `cat $CATALINA_PID`
    else
       echo "Kill failed: \$CATALINA_PID not set"
    fi
  fi

else
~

 ついでに? 因不昜 でプロセス停止しなかった時のスレッドダンプを残しておきます。デーモンスレッド以? のスレッドはなさそうなのですが、何かをwaitしています。JDKバージョンぜ 1.4.1_07。

Full thread dump Java HotSpot(TM) Server VM (1.4.1_07-b02 mixed mode):

"DestroyJavaVM" prio=1 tid=0x0x96fa078 nid=0x7357 waiting on condition [0..bfaab6fc]

"Signal Dispatcher" daemon prio=1 tid=0x0x9765830 nid=0x7357 waiting on condition [0..0]

"Finalizer" daemon prio=1 tid=0x0x975dab8 nid=0x7357 in Object.wait() [7b7d5000..7b7d51a4]
        at java.lang.Object.wait(Native Method)
        - waiting on <0x8136b928> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:111)
        - locked <0x8136b928> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:127)
        at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)

"Reference Handler" daemon prio=1 tid=0x0x975d678 nid=0x7357 in Object.wait() [7b856000..7b8561a4]
        at java.lang.Object.wait(Native Method)
        - waiting on <0x8136b530> (a java.lang.ref.Reference$Lock)
        at java.lang.Object.wait(Object.java:426)
        at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:113)
        - locked <0x8136b530> (a java.lang.ref.Reference$Lock)

"VM Thread" prio=1 tid=0x0x975cad8 nid=0x7357 runnable

"VM Periodic Task Thread" prio=1 tid=0x0x9764318 nid=0x7357 waiting on condition
"Suspend Checker Thread" prio=1 tid=0x0x9764d48 nid=0x7357 runnable