2016-09-02 7 views
0

私のアプリケーションでは、次のコードを使用して時間のセクションを作成しています。しかし、コードの下のは徐々にメモリをリークしますJlabelsetText()のためですか?日付と文字列を使用したメモリリークJava

誰でもエラーの特定にご協力いただけますか?

また、DateformatDateのメモリをjavaで解放する方法を教えてください。

Thread th= new Thread(new Runnable() { 

     public void run() { 
      DateFormat dateformat_s2= null; 
      Date date_int_s2=null; 
      String date_time_s2=null; 
      while(c==1) { 
       try { 
        Thread.sleep(50); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
       dateformat_s2= new SimpleDateFormat("dd:MM:yyyy HH:mm:ss"); 
       date_int_s2= new Date(); 
       date_time_s2 = dateformat_s2.format(date_int_s2); 
       time_end_label.setText(""+date_time_s2); 
       date_time_s2=null; 
       dateformat_s2=null; 
       date_int_s2=null; 
      } 
     } 
    }); 
+3

"次のコードではメモリが徐々にリークします。"どのようにこれをテストしていますか? Full GC後にどれだけのメモリを使用するかを印刷できますか? –

+0

目次別のスレッドでGUIコンポーネントを更新しないでください。私はGUI上でのみ更新をお勧めします。 –

+1

'dateformat'または 'date'のメモリを解放する必要はありません.Javaのガベージコレクタは自動的に余分にこれを整理します。 – Jason

答えて

4

メモリ使用量を監視するには、Full GC後に使用されたメモリを確認する必要があります。あなたがきれいになっているかもしれないが、まだ持っていないオブジェクトを持っているので、他のものは逃すでしょう。

注:値をnullに設定する必要はありません.GCは、移動するにつれてGCをクリーンアップするためです。ループ内のローカル変数を使用すると、反復ごとにオブジェクトを効果的に破棄することもできます。

注:1秒あたり20回ではなく、1秒に1回行うことができるように、次の秒まではどのように計算するかを計算できます。 ActionListenerのはあなたのためのGUIイベントループスレッドで実行されるようにスイングタイマーを使用する方が簡単だろうしかし

は、あなたがこの

public static void startTimer(JLabel time_end_label) { 
    Thread th = new Thread(new Runnable() { 

     public void run() { 
      DateFormat dateformat_s2 = new SimpleDateFormat("dd:MM:yyyy HH:mm:ss"); 
      while(!Thread.currentThread().isInterrupted()) { 
       Date date = new Date(); 
       final String date_time = dateformat_s2.format(date); 
       SwingUtilities.invokeLater(new Runnable() { 
        @Override 
        public void run() { 
         time_end_label.setText(date_time); 
        } 
       }); 
       long delay = 1000 - date.getTime() % 1000; 
       try { 
        Thread.sleep(delay); 
       } catch (InterruptedException e) { 
        break; 
       } 

      } 
     } 
    }); 
    th.setDaemon(true); 
    th.start(); 
} 

ようなコードを再書くことができます。

public static void startTimer(JLabel time_end_label) { 
    DateFormat dateformat= new SimpleDateFormat("dd:MM:yyyy HH:mm:ss"); 
    final ActionListener listener = new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      Date date = new Date(); 
      final String date_time = dateformat.format(date); 
      time_end_label.setText(date_time); 
      int delay = (int) (1000 - date.getTime() % 1000); 
      new Timer(delay, this).start(); 
     } 
    }; 
    new Timer(1, listener).start(); 
} 
+0

私はこれを試みたが、その動作しません。 Dateオブジェクトは徐々に4バイト増加しています。それを解放する方法。文字列に変換された場合、GCは日付オブジェクトのメモリを解放しません。それは参照のためである –

+0

@ Crystal_92 'date'リファレンスは毎回破棄されるので、あなたが示唆していることはできません。 StringはDateオブジェクトへの参照を保持しません。 'Date'オブジェクトは16バイトではなく24バイトです。Javaでは16バイト以下のオブジェクトを使用することはできません。 –

+0

だから、ここで何が問題になるでしょうか。このスレッドはより多くのRAMスペースを必要とします。私のアプリケーションが約5日間実行されているとき、アプリケーションは固執しています。今何ができますか?私を案内してください –

関連する問題