我有一个内存泄漏在我的java应用程序



新增信息:

在一个有用的主题的帮助下,我尝试了很多东西来摆脱JDialog(请参阅下面的完整信息)。我从这个主题的最后一个答案中重新编写了代码,添加了一个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)是与Listener中包含的5个相关行相同的类,并且还删除了Listener。

    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米之间的3d点)。我现在清理我的代码并重新编写不同的类。现在我得到内存使用问题,我不知道他们从哪里来的。

基本信息:

OS: Win 7 Ultimate 64 Bit SP1

内存:16GB

项目执行环境:javascript -1.7

由于这个项目非常复杂,我想很难提供一个运行的例子。在我用以下参数启动我的应用程序之后,基本步骤是:

- xx: -UseGCOverheadLimit

-Xms14g

-Xmx14g

以ascii格式加载一个点云,并将它们存储在一个point类(类名Point3D)中,实现vecmath库中的Point3f(对不起,名字混淆了),并将其可视化。执行以下操作之一,这些操作都在我的Gui中调用JDialog:

  • 空间聚类或者

  • 删除框内的删除点

每当我重做其中一个操作时,任务管理器中显示的内存使用情况就会扩大。让我们坚持删除点。我在gui中按下一个按钮,调用以下类:

Java不使用显式内存管理。对垃圾收集器的调用只是建议性的,JVM可能会忽略该调用。此外,空闲堆内存通常不会返回给操作系统(例如,它不像c++的删除调用);相反,它假设内存将在Java虚拟机中再次使用,并将对其进行管理。我不会给JVM 14GB的堆(-Xms14g -Xmx14g),除非我希望JVM 使用它。

相关内容

最新更新