2016-05-04 1 views
-3

JavaFXアプリケーションがあります。JavaFXアプリケーションには、データ処理に使用されるバックグラウンドスレッドが含まれており、ユーザーインターフェイスにその結果を表示します。 私は、データ処理のために、次のコード作成:問題は、私は、アプリケーションを実行し、「runningThread()」関数を実行するために、「スタート」ボタンをクリックした後、メモリやCPUの消費が高いですJavaアプリケーションはますます2GBまでのメモリを消費しています。

public static void runningThread(){ 
    long startTime = java.lang.System.nanoTime(); 

    WSN wsn = new WSN(100, 100, 30, 60, 200); 
    wsn.initializeNodePosition(); 
    wsn.alphaNodesDead = wsn.nodeNumber/2; 


    BaseStation BS = new BaseStation();           //the BS is created 
    BS.x = 125; 
    BS.y = 50; 
    BS.maxRadius = 65; 
    BS.energyModel = new NOEnergyModel(); 

    wsn.BS = BS; 
    BS.wsn = wsn; 



    Thread queryThread = new Thread() { 
     public void run() { 
      System.out.println("Start"); 

      for(int m=0; m<1000; m++){ 
       System.out.println(m); 

       wsn.protocol = new HEED(wsn); 
       wsn.generateHomogeneousWSN(HEEDNODE.class, new MITModel(), new SimpleAggregation()); 
       wsn.protocol.setRadiusAndNeighbors(); 


       boolean running = true; 
       while(running){ 
        wsn.roundPerformed++; 

        wsn.protocol.election_cluster_formation();    //cluster formation 
        wsn.defineStandardCHRouting();       //defines the routing at CH level 
        wsn.protocol.runRound(); 

        System.out.println(wsn.roundPerformed); 

        if(wsn.deadNodeList.size() >= wsn.alphaNodesDead){ 
         long stopTime = java.lang.System.nanoTime(); 

         System.out.println("end: " + (stopTime-startTime)/1000000000.0); 

         running = false; 
        } 
       } 
      } 

     } 
    }; 
    queryThread.start(); 
} 

をし、 2GB以上のメモリと90%のCPUに達すると、 "for(int m = 0; m < 1000; m ++)"ループが非常に遅くなります。各ループが始まる前にすべてのオブジェクトをクリアしています。 オブジェクトが参照を失ったら、JVMは自動的に再利用のためにメモリを再利用しますか?

答えて

1

それは時にJVMガベージコレクションキックでのよう「未定義」は

私はあなたの主要な問題は、ループが継続的に一時停止せずにテストしている間、あなたの内なるということだと思います - 。内部(100)のThread.sleepを追加してみてくださいwhileループ。

+0

スピードは遅くなりますが、他のヘルプはありません。ガベージコレクタはどのように呼び出すことができますか? – Albert

+0

System.gc()呼び出しでガベージコレクションをリクエストできます。 – Lee

1

メモリリークはコード内のどこにでも置くことができます。 IDEのVisualVMプロファイラまたはビルドインプロファイラを使用してそれを探します。

0

JVMは、未使用のオブジェクトのメモリを再利用しますが、GCプロセスが実行されるまで実行しません。私はrunRoundが多くのオブジェクトを内部的に割り当てていると推測します。おそらく、ループの次の反復でGCが実行されることはないので、新しいメモリが割り当てられ、次に何度も繰り返されます。

最終的にJVMの上限が(-Xmxパラメータ) GCは未使用のオブジェクトを解放するためにもっと積極的にキックを開始しますが、実際に発生するタイミングを制御することは実際にはありません。

VisualVMなどのツールを使用すると、問題の原因を特定するのに役立ちます。割り当てられたバイトと実際に使用されたバイトの違いが表示されます。 GCプロセスがいつ発生するかを見ることもできます。 VisualVMはJDKに含まれています。

もう1つの方法は、runRoundが何らかのグローバル参照を保持しているオブジェクトを割り当てることです。ここでも、VisualVMを慎重に使用すると、これを識別できるはずです。

+0

はい、runRoundは多くのことをしていますが、すべてがwsn.protocolを参照しています。ですから、各ループの始めに、私はwsn.protocol = new HEED(wsn)をやっています。すべてのものを初期化するために、前のループ内のすべてのオブジェクトが参照を失い、GCによってガーベジとみなされます。私はちょうど1000回シミュレーションを実行し、平均結果を取得したい。 – Albert

+0

ガベージコレクタを手動で呼び出すことはできますか? – Albert

+0

'System.gc()'を呼び出すことで実行することを提案できますが、実際に何かを行うことは保証されていません。既に割り当てられているオブジェクトのどれも再利用できないことを保証しているので、毎回新しいインスタンス「NEED」を作成するという戦略は逆効果になる可能性があることに注意してください。同じインスタンスを使用できる場合は、既存の配列などを再利用するほどスマートになる可能性があります。 – Stik

関連する問題