2014-03-25 24 views
0

新信息補充道:我必須在我的Java應用程序中的內存泄漏

我嘗試了很多東西來擺脫一個JDialog(參見下面的完整信息)與a helpful topic幫助。我返工從去年的答案代碼本主題中添加一個PropertyChangeListener,這似乎是在我真正的代碼問題:
運行,返工代碼1:

import java.awt.Dialog; 
import java.awt.Dimension; 
import java.awt.Window; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.beans.PropertyChangeEvent; 
import java.beans.PropertyChangeListener; 

import javax.swing.JDialog; 
import javax.swing.JFrame; 
import javax.swing.JOptionPane; 
import javax.swing.Timer; 

public class RemoveDialogOnruntimeListener extends JFrame { 

private static final long serialVersionUID = 1L; 
private boolean runProcess; 
private int maxLoop = 0; 
private Timer timer; 
private JOptionPane optionpane; 
private JDialog dialog; 

public RemoveDialogOnruntimeListener() { 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    setPreferredSize(new Dimension(300, 300)); 
    setTitle("Remove Dialog On Runtime"); 
    setLocation(150, 150); 
    pack(); 
    setVisible(true); 
    addNewDialog(); 
} 

private void addNewDialog() { 
    this.optionpane = new JOptionPane(); 
    this.dialog = optionpane.createDialog("Foo"); 
    dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); 
    dialog.setModalityType(Dialog.ModalityType.MODELESS); 
    dialog.setVisible(true); 
    this.optionpane.addPropertyChangeListener(new PropertyChangeListener() { 

     @Override 
     public void propertyChange(PropertyChangeEvent evt) { 
//    Object obj = evt.getNewValue(); 
//    System.out.println("----"); 
//    System.out.println(obj); 
      RemoveDialogOnruntimeListener.this.optionpane = null; 
      RemoveDialogOnruntimeListener.this.dialog = null; 
      remWins();  
      } 

     }); 
    } 




private void remWins() { 
    runProcess = true; 
    timer = new Timer(1000, new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      if (runProcess) { 
       for (Window win: Window.getWindows()) { 
        if (win instanceof JDialog) { 
         System.out.println(" Trying to Remove JDialog"); 
         win.dispose(); 
        } 
       } 
       System.out.println(" Remove Cycle Done :-)"); 
       runProcess = false; 
       new Thread() { 
        @Override 
        public void run() { 
         try { 
          Thread.sleep(100); 
         } catch (InterruptedException e) { 
          e.printStackTrace(); 
         } 
         Runtime.getRuntime().gc(); 
        } 
       }.start(); 
      } else { 
       if(maxLoop>=2){ 
        timer.stop(); 
       } else { 
        pastRemWins(); 
        runProcess = true; 
       } 

      } 
     } 
    }); 
    timer.setRepeats(true); 
    timer.start(); 
} 

private void pastRemWins() { 
    maxLoop++; 
    System.out.println(" Checking if still exists any of TopLayoutContainers"); 
    Window[] wins = Window.getWindows(); 
    for (int i = 0; i < wins.length; i++) { 
     if (wins[i] instanceof JFrame) { 
      System.out.println("JFrame"); 
     } else if (wins[i] instanceof JDialog) { 
      System.out.println("JDialog"); 
     } else { 
      System.out.println(wins[i].getClass().getSimpleName()); 
     } 
    } 
    // We must expect 2 windows here: this (RemoveDialogOnRuntime) and the parent of all parentless dialogs 
    if (wins.length > 2) { 
     wins = null; 

     if (maxLoop <= 3) { 
      System.out.println(" Will Try Remove Dialog again, CycleNo. " + maxLoop); 
      System.out.println(" -----------------------------------------------------------"); 
      remWins(); 
     } else { 
      System.out.println(" -----------------------------------------------------------"); 
      System.out.println("*** End of Cycle Without Success, Exit App ***"); 
      closeMe(); 
     } 
    } else { 
     timer.stop(); 
    } 
} 

private void closeMe() { 
    System.exit(0); 
} 


public static void main(String args[]) { 
    RemoveDialogOnruntimeListener superConstructor = new RemoveDialogOnruntimeListener(); 

} 
} 

在這個例子中,與聽者的使用, JDialog仍然會被刪除。我試着在相關代碼的工作,以我的實際類,如下所示:

public class DeleteInsideBox3DDialog { 

    Visu3DDeleteInsideBox visu; 
    JFormattedTextField xCoord,yCoord,zCoord; 
    SimpleTree simpleTree; 
    List<Point3D> lastDeleted; 
    Object[] options; 
    JDialog dialog; 
    JOptionPane optionPane; 
    private boolean runProcess; 
     private int maxLoop = 0; 
     private Timer timer; 

    public DeleteInsideBox3DDialog(SimpleTree simpleTree, Visu3DDeleteInsideBox visu) { 
     this.simpleTree = simpleTree; 
     this.visu = visu; 
     this.lastDeleted = new ArrayList<Point3D>(); 
     this.options = new String[] { "Done" }; 
     Object complexMsg[] = { centerXPanel(),centerYPanel(),centerZPanel() 
       ,dimXPanel(),dimYPanel(),dimZPanel() 
       ,deleteButtonPanel(),undeleteButtonPanel() }; 
     this.optionPane = new JOptionPane(); 

     this.optionPane.setMessage(complexMsg); 
     this.optionPane.setOptions(this.options); 
     this.optionPane.setMessageType(JOptionPane.PLAIN_MESSAGE); 
//   this.dialog = this.optionPane.createDialog(this.simpleTree.getGui() 
//     .getMonitor().getSelectedComponent(), 
//     "Delete Points contained in a box"); 
      this.dialog = this.optionPane.createDialog("Delete Points contained in a box"); 
      this.dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); 
     this.dialog.setModalityType(Dialog.ModalityType.MODELESS); 
//  this.dialog.setSize(800, 400); 
     this.dialog.setVisible(true); 
     this.dialog.setVisible(false); 
     this.dialog.setVisible(true); 
     this.dialog.pack(); 
     this.optionPane.addPropertyChangeListener(new PropertyChangeListener() { 

      @Override 
      public void propertyChange(PropertyChangeEvent evt) { 
       Object obj = evt.getNewValue(); 
       int result = -1; 
       for (int k = 0; k < DeleteInsideBox3DDialog.this.options.length; k++) { 
        if (DeleteInsideBox3DDialog.this.options[k].equals(obj)) { 
         result = k; 
        } 
       } 

       if (result == 0) { 
        DeleteInsideBox3DDialog.this.optionPane = null; 
        DeleteInsideBox3DDialog.this.dialog.setVisible(false); 
        DeleteInsideBox3DDialog.this.dialog.dispose(); 
        DeleteInsideBox3DDialog.this.dialog = null; 
        remWins(); 
//     Visu3DDeleteInsideBox visuOld = (Visu3DDeleteInsideBox) DeleteInsideBox3DDialog.this.simpleTree.getGui().getMonitor().getSelectedComponent(); 
//     visuOld.setDialog(null); 
//     DeleteInsideBox3DDialog.this.visu = null; 
//     Monitor monitor = DeleteInsideBox3DDialog.this.simpleTree.getGui().getMonitor(); 
//     monitor.removeAll(); 
//     monitor.revalidate(); 
//     new Thread() { 
//      @Override 
//      public void run() { 
//       try { 
//        Thread.sleep(100); 
//       } catch (InterruptedException e) { 
//        e.printStackTrace(); 
//       } 
//       Runtime.getRuntime().gc(); 
//      } 
//     }.start(); 
        //Visu3dBasic visu = new Visu3dBasic(DeleteInsideBox3DDialog.this.simpleTree, monitor.getWidth(), monitor.getHeight()); 
        //monitor.add(visu,DeleteInsideBox3DDialog.this.simpleTree.getModel().getTreeID()); 
        //DeleteInsideBox3DDialog.this.optionPane.removeAll(); 
//     DeleteInsideBox3DDialog.this.optionPane = null; 
        //DeleteInsideBox3DDialog.this.dialog.setVisible(false); 
        //DeleteInsideBox3DDialog.this.dialog.dispose(); 
//     DeleteInsideBox3DDialog.this.dialog = null; 
//     DeleteInsideBox3DDialog.this.remWins();     
       } 

      } 
     }); 
//  this.optionPane = null; 
//  this.dialog.setVisible(false); 
//  this.dialog.dispose(); 
//  this.dialog = null; 
//  remWins();  

    } 

    private void remWins() { 
     runProcess = true; 
     timer = new Timer(1000, new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       if (runProcess) { 
        for (Window win: Window.getWindows()) { 
         if (win instanceof JDialog) { 
          System.out.println(" Trying to Remove JDialog"); 
          try { 
           win.getParent().remove(win); 
          } catch (Exception e1) { 

          } 
          ((JDialog) win).setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); 
          ((Dialog) win).setModalityType(Dialog.ModalityType.MODELESS); 

          win.dispose(); 
         } 
        } 
        System.out.println(" Remove Cycle Done :-)"); 
        runProcess = false; 
        new Thread() { 
         @Override 
         public void run() { 
          try { 
           Thread.sleep(100); 
          } catch (InterruptedException e) { 
           e.printStackTrace(); 
          } 
          Runtime.getRuntime().gc(); 
         } 
        }.start(); 
       } else { 
        if(maxLoop>=2){ 
         timer.stop(); 
        } else { 
         pastRemWins(); 
         runProcess = true; 
        } 

       } 
      } 
     }); 
     //timer.setRepeats(true); 
     timer.start(); 
    } 

    private void pastRemWins() { 
     System.out.println(" Checking if still exists any of TopLayoutContainers"); 
     Window[] wins = Window.getWindows(); 
     for (int i = 0; i < wins.length; i++) { 
      if (wins[i] instanceof JFrame) { 
       System.out.println("JFrame"); 
      } else if (wins[i] instanceof JDialog) { 
       System.out.println("JDialog"); 
      } else { 
       System.out.println(wins[i].getClass().getSimpleName()); 
      } 
     } 
     // We must expect 2 windows here: this (RemoveDialogOnRuntime) and the parent of all parentless dialogs 
     if (wins.length > 2) { 
      wins = null; 
      maxLoop++; 
      if (maxLoop <= 3) { 
       System.out.println(" Will Try Remove Dialog again, CycleNo. " + maxLoop); 
       System.out.println(" -----------------------------------------------------------"); 
       remWins(); 
      } else { 
       System.out.println(" -----------------------------------------------------------"); 
       System.out.println("*** End of Cycle Without Success, Exit App ***"); 
       //System.exit(0); 
       timer.stop(); 
      } 
     } else { 
      timer.stop(); 
     } 
    } 


} 

這沒有運行,什麼是實際運行中類(其中的JDialog被刪除)是同一類包含在5個相關行聽衆也放棄了聽衆。

public DeleteInsideBox3DDialog(SimpleTree simpleTree, Visu3DDeleteInsideBox visu) { 
     this.simpleTree = simpleTree; 
     this.visu = visu; 
     this.lastDeleted = new ArrayList<Point3D>(); 
     this.options = new String[] { "Done" }; 
     Object complexMsg[] = { centerXPanel(),centerYPanel(),centerZPanel() 
       ,dimXPanel(),dimYPanel(),dimZPanel() 
       ,deleteButtonPanel(),undeleteButtonPanel() }; 
     this.optionPane = new JOptionPane(); 

     this.optionPane.setMessage(complexMsg); 
     this.optionPane.setOptions(this.options); 
     this.optionPane.setMessageType(JOptionPane.PLAIN_MESSAGE); 
//   this.dialog = this.optionPane.createDialog(this.simpleTree.getGui() 
//     .getMonitor().getSelectedComponent(), 
//     "Delete Points contained in a box"); 
      this.dialog = this.optionPane.createDialog("Delete Points contained in a box"); 
      this.dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); 
     this.dialog.setModalityType(Dialog.ModalityType.MODELESS); 
//  this.dialog.setSize(800, 400); 
     this.dialog.setVisible(true); 
     this.dialog.setVisible(false); 
     this.dialog.setVisible(true); 
     this.dialog.pack(); 
//  this.optionPane.addPropertyChangeListener(new PropertyChangeListener() { 
//   
//   @Override 
//   public void propertyChange(PropertyChangeEvent evt) { 
//    Object obj = evt.getNewValue(); 
//    int result = -1; 
//    for (int k = 0; k < DeleteInsideBox3DDialog.this.options.length; k++) { 
//     if (DeleteInsideBox3DDialog.this.options[k].equals(obj)) { 
//      result = k; 
//     } 
//    } 
// 
//    if (result == 0) { 
////     DeleteInsideBox3DDialog.this.optionPane = null; 
////     DeleteInsideBox3DDialog.this.dialog.setVisible(false); 
////     DeleteInsideBox3DDialog.this.dialog.dispose(); 
////     DeleteInsideBox3DDialog.this.dialog = null; 
////     remWins(); 
////     Visu3DDeleteInsideBox visuOld = (Visu3DDeleteInsideBox) DeleteInsideBox3DDialog.this.simpleTree.getGui().getMonitor().getSelectedComponent(); 
////     visuOld.setDialog(null); 
////     DeleteInsideBox3DDialog.this.visu = null; 
////     Monitor monitor = DeleteInsideBox3DDialog.this.simpleTree.getGui().getMonitor(); 
////     monitor.removeAll(); 
////     monitor.revalidate(); 
////     new Thread() { 
////      @Override 
////      public void run() { 
////       try { 
////        Thread.sleep(100); 
////       } catch (InterruptedException e) { 
////        e.printStackTrace(); 
////       } 
////       Runtime.getRuntime().gc(); 
////      } 
////     }.start(); 
//     //Visu3dBasic visu = new Visu3dBasic(DeleteInsideBox3DDialog.this.simpleTree, monitor.getWidth(), monitor.getHeight()); 
//     //monitor.add(visu,DeleteInsideBox3DDialog.this.simpleTree.getModel().getTreeID()); 
//     //DeleteInsideBox3DDialog.this.optionPane.removeAll(); 
////     DeleteInsideBox3DDialog.this.optionPane = null; 
//     //DeleteInsideBox3DDialog.this.dialog.setVisible(false); 
//     //DeleteInsideBox3DDialog.this.dialog.dispose(); 
////     DeleteInsideBox3DDialog.this.dialog = null; 
////     DeleteInsideBox3DDialog.this.remWins();     
//    } 
//    
//   } 
//  }); 
     this.optionPane = null; 
     this.dialog.setVisible(false); 
     this.dialog.dispose(); 
     this.dialog = null; 
     remWins();  

    } 

兩個真正的代碼片段唯一的區別似乎是接收器從工作到不工作改變一切的使用,但是當我試圖生產示例代碼,還與監聽器的代碼工作。

編輯之前:

我具有用於處理地面激光掃描數據(1百萬和20 MIO 3D點之間)編寫的應用程序。我現在清理我的代碼並修改不同的類。現在我得到了內存使用問題,我不知道它們來自哪裏。

基本信息:

OS:Win 7的旗艦版64位SP1

內存:16GB

項目執行環境:JavaSE的-1.7

由於該項目是安靜複雜,我猜提供一個運行的例子將是非常困難的。 基本的步驟,之後我用下面的參數開始我的應用程序是:

-XX:-UseGCOverheadLimit

-Xms14g

-Xmx14g

負載點雲在ASCI格式,並將其儲存在一個Point類(類名Point3D)中實現Point3f(對於令人困惑的名字),從vecmath lib中實現並可視化。 執行下列操作之一,這些都調用一個JDialog在我的GUI:

  • 空間聚類 或

  • 刪除點刪除框

每當我重做內其中一個操作,任務管理器中顯示的內存使用情況將被放大。讓我們堅持刪除積分。 我在我的gui中按下了一個按鈕,調用以下類:

+0

你不覺得這個問題屬於[codereview](http://codereview.stackexchange.com/)嗎? –

+1

是否重複使用了JDialog ???,否則每增加一個使用JVM內存的新實例, – mKorbel

+0

不知道codereview,我是否可以像這樣「標記」這個主題,還是必須重新發布嗎? – BuddhaWithBigBelly

回答

0

Java不使用顯式內存管理。您對垃圾收集器的調用只是建議性的,JVM可能會忽略該調用。此外,空閒堆內存通常不會返回到操作系統(例如,它不像C++刪除調用);相反,它假定內存將在Java虛擬機中再次使用,它將管理該內存。我不會給JVM 14GB的堆(-Xms14g -Xmx14g),除非我想讓JVM到使用它。

+0

@ Elliot frish我想用-Xms選項我同意和你在一起,但我試過索姆在子技嘉的東西,這導致了內存不足的情況下,所以爲了簡單起見,我只是把它放在最大的堆空間相同的價值。而這,是的,我想給我的應用程序的最大內存量,所以這裏14 GB對我來說很好(以前用這個數量與20mio數據點操作,雖然正如我所說,我正在嘗試清理)。 – BuddhaWithBigBelly

+0

對於你答案的第一部分,我知道你永遠不能強迫GC工作,給他一個很好的「請爲我做這個」。我還假定內存不會回饋給操作系統,但是對於JVM,它現在應該是「空閒內存」,因此在後續進程鏈中不應該保留更多的內存。 – BuddhaWithBigBelly

+0

@BuddhaWithBigBelly只適用於堆;它可能仍會增加堆棧。 –

相關問題