2011-07-27 13 views
0

whileループを使用してAmazon SQSからメッセージを取得しました。部分コードは次のとおりです。java whileループメモリリーク

ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest(myQueueUrl); 
while (true) { 
    List<Message> messages = sqs.receiveMessage(receiveMessageRequest).getMessages(); 

    if (messages.size() > 0) { 

      MemcachedClient c = new MemcachedClient(new BinaryConnectionFactory(), AddrUtil.getAddresses(memAddress)); 

      for (Message message : messages) { 

       // get message from aws sqs 
       String messageid = message.getBody(); 
       String messageRecieptHandle = message.getReceiptHandle(); 
       sqs.deleteMessage(new DeleteMessageRequest(myQueueUrl, messageRecieptHandle)); 

       // get details info from memcache 
       String result = null; 
       String key = null; 
       key = "message-"+messageid; 
       result = c.get(key); 

      } 
      c.shutdown(); 
      } 
     } 

このような場合にメモリリークが発生しますか? "ps aux"を使ってチェックしました。私が見つけたのは、RSS(常駐セットサイズ、タスクが使用したスワップされていない物理メモリ)がゆっくりと成長していることです。

+0

ループ内の変数を定義しています。定義をループの上に移動し、ループ内で再利用/再割り当てします。 –

+0

それは単にオーバーヘッドを増やす、彼らは同じポインタを使用していますか? –

+1

@ D.N:重要な違​​いはありません。コンパイラは、必要なローカルをスタックに1回だけ割り当てることができるほどスマートです。 –

答えて

1

申し訳ありませんが、メッセージキューからメッセージを削除するコードはありません。あなたはメッセージリストをきれいにしましたか? DeleteRequestがキューからメッセージを削除する場合は、そのメッセージのリストを変更しようとします。

さらに、JDKの一部であるvisualvmツールを使用すると、より良いメモリ使用統計を取得できます。

+0

反復ごとにオブジェクトへの参照を削除する必要があります。だから、リストのサイズは問題を起こさないはずです –

+0

リストメッセージをきれいにしません。リストからメッセージを受け取り、SQSからメッセージを削除します。しかし、リストメッセージには触れません。次の反復では、List メッセージはSQSからの新しいメッセージのリストを取得します。それって問題ですか? – chnet

+0

@chnet:あなたのSQSが問題を引き起こすかどうかは疑問です。メッセージは、SQSから受信したオブジェクトを指す別の参照でなければなりません。 OKであるべきです –

2

Javaアプリケーションに単純にプロセスのRSSに基づいてメモリリークがあるかどうかを評価することはできません。ほとんどのJVMはかなり貪欲で、ガベージコレクションに多くの作業を費やすよりも、OSより多くのメモリを取ることになります。

あなたのwhileループに明白なメモリ "リーク"があるようには思えませんが、それはメソッド呼び出しのいくつか(上記には含まれていません)に依存します。静的変数に物事を格納している場合は、それが懸念の原因になる可能性がありますが、唯一の参照がループのスコープ内にあれば、おそらく問題ありません。

特定のコード領域でメモリリークが発生しているかどうかを確認する最も簡単な方法は、アプリケーションの1回の実行でそのコードを厳密に実行することです(潜在的に最大ヒープサイズが小さく設定されている可能性があります)。 OutOfMemoryErrorを取得した場合、メモリリークが発生している可能性があります。