2

メッセージ配信オプションが PERSISTENT に設定された組み込みブローカーとして、Tomcat 6.0.35 で activeMQ5.6 を実行しています。コンシューマ側の 1 つで OutOfMemory 問題が発生しています。消費者は、時間のかかる仕事をしているので遅いです。以前は、8 ~ 10 時間実行した後に OOM を取得していました。3000 件のメッセージを処理した後、OOM を与えるナットを処理する必要があるメッセージが最大 10000 件あり、残りの 7000 件のメッセージが保留状態に保持されます。メッセージのサイズは非常に小さく、xml 形式で約 1KB です。非常に高速な diff キューに他のコンシューマがあり、そこにも ~10000 のメッセージが発行され、メッセージ サイズは ~100 KB とかなり大きくなりますが、そのキューで OOM を取得していません。同じブローカーにセットアップされていますが。

エラーのスタック トレースと出力の activemq.xml ファイルを次に示します。

INFO [11/08/12 05:39:31]ActiveMQ セッション タスク 4- Nam2011_08_prototype/gdfas/mnada/usa/uf3.7z.001 の Amazon S3 バケットへのアップロードの開始 - aws-s3-infotech スレッド「InactivityMonitor WriteCheck での例外」 " java.lang.OutOfMemoryError: java.lang.Thread.start0(Native Method) で java.lang.Thread.start(Thread.java:640) で新しいネイティブ スレッドを作成できません。 (ThreadPoolExecutor.java:727) で java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:657) で org.apache.activemq.transport.AbstractInactivityMonitor.writeCheck(AbstractInactivityMonitor.java:142) で org.apache.activemq. transport.AbstractInactivityMonitor$2.run(AbstractInactivityMonitor.java:111) org.apache.activemq.thread.SchedulerTimerTask.run(SchedulerTimerTask.java:33) で java.util.TimerThread.mainLoop(Timer.java:512) で java.util.TimerThread.run(Timer.java:462) )

これはactivemq.xmlからのスナップショットです

 <persistenceAdapter>
  <kahaDB directory="${activemq.data}/kahadb"/>
</persistenceAdapter>

<transportConnectors>
  <!-- <transportConnector name="openwire" uri="tcp://localhost:61616"/> -->
  <transportConnector name="openwire" uri="tcp://0.0.0.0:61616"/>
  <transportConnector name="stomp" uri="stomp://localhost:61613"/>
</transportConnectors>

<networkConnectors>
  <!-- by default just auto discover the other brokers -->
  <networkConnector name="defaultNetwork" uri="multicast://default"/>
  <!--
  <networkConnector name="host1 and host2" uri="static://(tcp://host1:61616,tcp://host2:61616)" failover="true"/>
  -->
</networkConnectors>

<systemUsage>
        <systemUsage>
            <memoryUsage>
                <memoryUsage limit="512 mb"/>
            </memoryUsage>
            <storeUsage>
                <storeUsage limit="100 gb"/>
            </storeUsage>
            <tempUsage>
                <tempUsage limit="50 gb"/>
            </tempUsage>
        </systemUsage>
    </systemUsage>

<!--  lets define the dispatch policy -->
<destinationPolicy>
  <policyMap>
    <policyEntries>
      <policyEntry queue="SyncServer.>"  memoryLimit="512mb" optimizedDispatch="true" queuePrefetch="10">
    <pendingQueuePolicy>
            <fileQueueCursor/>
        </pendingQueuePolicy>          
      </policyEntry>
   </policyEntries>
  </policyMap>
</destinationPolicy>
4

1 に答える 1

5

これは ActiveMQ とは関係ありません。エラー

java.lang.OutOfMemoryError: 新しいネイティブ スレッドを作成できません

スレッドに割り当てる十分な空きメモリが OS にないことを意味します。私が考える方法は、Javaが作成するすべてのスレッドについて、OSが「ネイティブ」スレッドを作成できる必要があり、それにはメモリが必要です。マシンのメモリを解放するか、メモリを追加する必要があります。または、ほとんどの場合、直観に反して、実際にはヒープ割り当てを減らして、OS により多くを残す必要があります。

一般的な経験則では、JVM に割り当てるときに、少なくとも OS 用に空きメモリを残しておく必要があります。たとえば、2GB のヒープがある場合は、そこに少なくとも 2GB の空き領域が必要です (OS もメモリを使用することを考慮してください)。

JVM設定、OS、64/32ビットで回答を更新する場合は? ハードウェアのチューニングをお手伝いします。

于 2012-08-28T20:07:39.940 に答える