0

Java アプリケーションにメモリ リークがあります。リソースをクリアするコードがタスク マネージャを実行しているときに、メモリ使用量が変更されていないことが示されます。私のコード

while (isRunning) {
      try 
      {

             selector.select(); 

             long sum=0;

             Set keys =  selector.selectedKeys();
             Iterator it = keys.iterator(); 
             while(it.hasNext())
             {
                 SelectionKey key = (SelectionKey)it.next();
                 if (key.isReadable())
                 { 
                      SocketChannel sc = (SocketChannel) key.channel();

                      ByteBuffer bb;
                      if(key.attachment()==null)
                      {
                          bb = ByteBuffer.allocate(1024*1024);
                          key.attach(bb);
                      }
                      else
                      {
                          bb = (ByteBuffer)key.attachment();
                          bb.clear();
                      }

                      int x =  sc.read(bb); 

                       System.out.println(x +" bytes were read");
                       if(x==-1)
                       {
                           key.attach(null); //doesn't work
                           sc.close();
                           //bb = null; // also doesn't work
                       }
                 } 
             }
           keys.clear();
      } 
      catch (Exception ex) 
      {     
          ex.printStackTrace(new PrintStream(System.out));
      }
      finally
      { 
            //stopServer();
      }
    }

テスト ロジック - サーバーに 100 個のメッセージを送信する単純な TCP クライアント Java プログラムを作成しました。意図的に大きなバッファー (接続ごとに 1MB) を割り当てました。クライアントがジョブを終了するint x = sc.read(bb);と -1 が返され、次のコードが実行されます。

if(x==-1)
                           {
                               key.attach(null); //doesn't work
                               sc.close();
                               //bb = null; // also doesn't work
                           }

デバッグ出力で確認したところ、このコードは実際に実行されましたが、タスク マネージャーは依然として大量のメモリ使用量を示しています。問題はどこだ?

4

1 に答える 1

2

確かkey.attach(null)に動作します。そうでない場合、null 以外のオブジェクトをアタッチしても機能しません。同じコード。

ただし、いずれにせよ、を閉じるとキーがSocketChannelキャンセルされ、登録されていたすべてのキーセットからキーが削除されるSelectorsため、キーが再び表示されることはありません。key.attach(null)したがって、これは冗長です。添付ファイルへの別の参照が別の場所にあるか、メモリ使用量の問題が別の場所にあります。

于 2013-07-15T11:07:45.510 に答える