Swing 中的内存泄漏

发布于 2024-12-12 05:53:39 字数 17203 浏览 0 评论 0原文

一个应用程序Swing(GUI),一个目的地信息终端。 VirtualVM 分析器显示,泄漏是由于

java.awt.image.DataBufferInt

и

sun.awt.image.ImageRepresentation.setPixels

发生的,在形式之间的转换期间发生了内存的增加。

应用逻辑有几种形式(JFrame - JF1、JF2 ... JF7)。 JF1基本窗体,按JButtons打开其他窗体,自行关闭等。除JF1外,其他窗体都有按钮<>。窗体中有很多带有图片的JButton,用到了FancyButton:

public class FancyButton extends JButton {
    private static final long serialVersionUID = 1L;

    public FancyButton(Icon icon, Icon pressed) {
        super(icon);
        setFocusPainted(false);
        //setRolloverEnabled(treue);
        //setRolloverIcon(rollover);
        setPressedIcon(pressed);
        setBorderPainted(false);
        setContentAreaFilled(false);
    }
}

窗体上的JButton绘制如下:

public class JF1 extends JFrame {

    private static final GridBagConstraints gbc;
    public static Timer tmr;

    public JF1() throws Exception{
        setUndecorated(true);
        GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().setFullScreenWindow(this);
        setAlwaysOnTop(true);
        setLayout(new GridBagLayout());
        setTitle("JF1");
    }

    public void init() throws Exception{

        GlobalVars.jf2 = null;
        GlobalVars.jf3 = null;
        GlobalVars.jf4 = null;
        GlobalVars.jf5 = null;
        GlobalVars.jf6 = null;
        GlobalVars.jf7 = null;
        JXPanel contentPane = new JXPanel();
                try {
                ImagePainter ip = new ImagePainter(ImageIO.read(new File("skins/bg.jpg")));
                ip.setFillHorizontal(true);
                ip.setFillVertical(true);
                contentPane.setBackgroundPainter(ip);
             } catch (Exception e) {
                e.printStackTrace();
             }


        Panel p01 = new Panel();
        GridLayout gl01 = new GridLayout(1, 8, 2, 2);
        p01.setLayout(gl01);
        p01.setLocation(200, 300);
        ResultSet rs = GlobalVars.st.executeQuery("select * from last_use_service order by nomer");
        Icon i1;
        Icon i2;
        while (rs.next()){
            final int l = rs.getInt(2);
            i1 = new ImageIcon("skins/oper_logos/" + l + ".png");
            i2 = new ImageIcon("skins/oper_logos/" + l + "_off.png");

            FancyButton jbt = new FancyButton(i1,i2 );
            jbt.setBounds(10, 100, 100, 100);

            jbt.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent event) {
                    tmr.stop();     

                    if(GlobalVars.jf3==null)
                                            GlobalVars.jf3 = new JF3();
                    GlobalVars.jf3.init(); 
                    GlobalVars.jf3.setVisible(true);            // Так открывается новая форма
                    setVisible(false);                              // и закрывается текущая
                    dispose();
                }
            });
            p01.add(jbt);
        }
        rs.close();
        addComponent(panel, p01, 0, 1, 2, 1, GridBagConstraints.WEST,GridBagConstraints.NORTHWEST);
...

首先启动的主类:

public class Main {

    public static class GlobalVars{

        public static String TypeDB = "MySQL";  
        public static Connection DataBase;
        public static Statement st;     

        public static JF1 jf1;          // JFrame
        public static JF2 jf2;          // JFrame
        public static JF3 jf3;          // JFrame
        ...
    }

    public static void main(String[] args) throws Exception {
        if(GlobalVars.TypeDB.equals("MySQL")){
            Class.forName("com.mysql.jdbc.Driver");
            GlobalVars.DataBase = DriverManager.getConnection("jdbc:mysql://localhost:3306/terminal?lc_ctype=UTF8", "root","123");

                if(GlobalVars.jf1==null)
                    GlobalVars.jf1 = new JF1();
        GlobalVars.jf1.init();
        GlobalVars.jf1.setVisible(true);
        }
...
       }

还是在Forms的Init方法中,有一个定时器,过了一段时间后,打开主窗体,关闭当前的:

...
tmr = new Timer( s * 1000, updateCursorAction);
tmr.start();
...
private Action updateCursorAction = new AbstractAction() {
        public void actionPerformed(ActionEvent e) {
            if(GlobalVars.jf1==null){
                try {
                    GlobalVars.jf1= new JF1();
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
            }
            tmr.stop();
            try {
                GlobalVars.jf1.init();
            } catch (Exception e1) {
                e1.printStackTrace();
            }
            GlobalVars.jf1.setVisible(true);
            GlobalVars.jf2 = null;
            setVisible(false);
            dispose();      
        }
    };

堆转储 请帮助修复内存泄漏。

我已将所有面板更改为 JPanel,这就是 JF1 的代码:

package PlatService;

import java.awt.*;

public class JF1 extends JFrame {
    private static final long serialVersionUID = 1L;
    //private static final Insets insets = new Insets(0, 0, 0, 0);
    private static String[] arrLang = { "rus", "eng", "taj" };
    private static final GridBagConstraints gbc;
    public static Timer tmr;

    static {

    public JF1() throws Exception{
        setUndecorated(true);
        GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().setFullScreenWindow(this);
        setAlwaysOnTop(true);
        setLayout(new GridBagLayout());
        setTitle("JF1");
    }

    public void init() throws Exception{

        GlobalVars.jf2 = null;
        GlobalVars.jf3 = null;
        GlobalVars.jf4 = null;
        GlobalVars.jf5 = null;
        GlobalVars.jf6 = null;
        GlobalVars.jf7 = null;
        JXPanel contentPane = new JXPanel();
        try {
                ImagePainter ip = new ImagePainter(ImageIO.read(new File("skins/bg.jpg")));
                ip.setFillHorizontal(true);
                ip.setFillVertical(true);
                contentPane.setBackgroundPainter(ip);
        } catch (Exception e) {
                e.printStackTrace();
        }
        //setContentPane(contentPane);
        JPanel panel = new JPanel();
        panel.setLayout(new GridBagLayout());
        addComponent(this, panel, 0, 0, 1, 1, GridBagConstraints.CENTER ,GridBagConstraints.BOTH);

        JPanel p0 = new JPanel();
        GridLayout gl0 = new GridLayout(1, 1, 1, 1);
        final JLabel jl = new JLabel(new ImageIcon("skins/logo.png"));
        p0.setLayout(gl0);
        p0.add(jl);
        addComponent(panel, p0, 0, 0, 2, 1, GridBagConstraints.NORTH ,GridBagConstraints.NORTH);


        JPanel p01 = new JPanel();
        GridLayout gl01 = new GridLayout(1, 8, 2, 2);
        p01.setLayout(gl01);
        p01.setLocation(200, 300);
        ResultSet rs = GlobalVars.st.executeQuery("select * from last_use_service order by nomer");
        Icon i1;
        Icon i2;
        while (rs.next()){
            final int l = rs.getInt(2);
            i1 = new ImageIcon("skins/oper_logos/" + l + ".png");
            i2 = new ImageIcon("skins/oper_logos/" + l + "_off.png");
            FancyButton jbt = new FancyButton(i1,i2 );
            jbt.setBounds(10, 100, 100, 100);
            jbt.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent event) {
                    tmr.stop();
                    GlobalVars.OperId = l;
                    GlobalVars.getCashCode=false;
                    if(GlobalVars.jf3==null)GlobalVars.jf3 = new JF3();
                    GlobalVars.jf3.init(); // = new JF3();
                    GlobalVars.jf3.setVisible(true);
                    setVisible(false);
                    dispose();
                }
            });
            p01.add(jbt);
        }
        rs.close();
        addComponent(panel, p01, 0, 1, 2, 1, GridBagConstraints.WEST,GridBagConstraints.NORTHWEST);

        if (GlobalVars.LangId < 0 || GlobalVars.LangId > 2)GlobalVars.LangId = 0;

        String sql = "SELECT * FROM OpGroup WHERE parent=0 order by enable desc, order_n";
        PreparedStatement psmnt = GlobalVars.DataBase.prepareStatement(sql);
        ResultSet rs2 = psmnt.executeQuery();

        //rs = GlobalVars.st.executeQuery();
        JPanel p = new JPanel();
        GridLayout gl = new GridLayout(0, 2, 2, 2);
        p.setLayout(gl);
        p.setSize(300, 400);
        p.setLocation(200, 300);        
        while (rs2.next()){
            final int l = rs2.getInt(2);
            i1 = new ImageIcon("skins/"+ arrLang[GlobalVars.LangId]+"/services/" + l + ".png");
            i2 = new ImageIcon("skins/"+ arrLang[GlobalVars.LangId]+"/services/" + l + "_off.png");
            FancyButton jbt = new FancyButton(i1,i2);
            jbt.setBounds(10, 100, 100, 100);
            if(rs2.getInt("enable")==1){
                jbt.setEnabled(true);
            }else{
                jbt.setEnabled(false);
            }
            jbt.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent event) {
                    GlobalVars.getCashCode=false;
                    try {
                        tmr.stop();
                        ActionPerformed(event, GlobalVars.LangId, l);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
            p.add(jbt);
        }
        addComponent(panel, p, 0, 2, 1, 1, GridBagConstraints.NORTH,GridBagConstraints.NORTH);
        rs2.close();
        JPanel p1 = new JPanel();
        GridLayout gl1 = new GridLayout(5, 1, 5, 5);
        // setLayout(new GridLayout(3, 4, 2, 2));
        p1.setLayout(gl1);
        // p2.setSize(300, 400);
        // p2.setLocation(200, 300);

        for (int i = 0; i < arrLang.length; i++) {
            final int l = i;
            i1 = new ImageIcon("skins/button_" + arrLang[i] + ".png");
            i2 = new ImageIcon("skins/button_" + arrLang[i] + "_off.png");
            FancyButton jbt = new FancyButton(i1, i2);
            jbt.setBounds(10, 100, 100, 100);
            //if (i == GlobalVars.LangId) {jbt.setEnabled(false);}
            jbt.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent event) {
                    //Play.stop();
                    GlobalVars.LangId = l;
                    GlobalVars.getCashCode=false;
                    GlobalVars.jf1 = null;
                    try {
                        GlobalVars.jf1 = new JF1();
                    } catch (Exception e1) {
                        e1.printStackTrace();
                    }
                    try {
                        GlobalVars.jf1.init();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    tmr.stop();
                    GlobalVars.jf1.setVisible(true);
                    setVisible(false);
                }
            });
            p1.add(jbt);
        }
        i1 = new ImageIcon("skins/" + arrLang[GlobalVars.LangId] + "/services/button_help.png");
        i2 = new ImageIcon("skins/" + arrLang[GlobalVars.LangId] + "/services/button_help_off.png");
        FancyButton jbt_help = new FancyButton(i1,i2);
        jbt_help.setBounds(10, 100, 100, 100);
        jbt_help.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                tmr.stop();
                GlobalVars.getCashCode=false;
                GlobalVars.jf1 = null;
                try {
                    GlobalVars.jf1 = new JF1();
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
                try {
                    GlobalVars.jf1.init();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                GlobalVars.jf1.setVisible(true);
                setVisible(false);
            }
        });
        p1.add(jbt_help);
        i1 = new ImageIcon("skins/" + arrLang[GlobalVars.LangId] + "/services/button_about.png");
        i2 = new ImageIcon("skins/" + arrLang[GlobalVars.LangId] + "/services/button_about_off.png");
        FancyButton jbt_about = new FancyButton(i1,i2);
        jbt_about.setBounds(10, 100, 100, 100);

        p1.add(jbt_about);
        addComponent(panel, p1, 1, 2, 1, 1, GridBagConstraints.EAST,GridBagConstraints.EAST);

        JPanel p011 = new JPanel();
        GridLayout gl011 = new GridLayout( 1, 1, 1, 1);
        gl011.setVgap(1);
        JLabel jl12 = new JLabel("<html><hr></html>", JLabel.LEFT);
        jl12.setAlignmentX(TOP_ALIGNMENT);
        jl12.setBackground(Color.red);
        p011.setLayout(gl011);
        p011.add(jl12);
        p011.setSize(10, 90);
        addComponent(panel, p011, 0, 3, 4, 1, GridBagConstraints.WEST, GridBagConstraints.NORTH);


        JPanel p0112 = new JPanel();
        GridLayout gl0112 = new GridLayout( 1, 1, 1, 1);
        gl0112.setVgap(1);
        JLabel jl122 = new JLabel("<html><hr><H2>"+GlobalVars.StatusMessage[GlobalVars.LangId]+"</H2></html>", JLabel.CENTER);
        jl122.setAlignmentX(TOP_ALIGNMENT);
        p0112.setLayout(gl0112);
        p0112.add(jl122);
        p0112.setSize(10, 90);

        addComponent(this, p0112, 0, 5, 5, 1, GridBagConstraints.SOUTH, GridBagConstraints.BOTH);

        if(!GlobalVars.stTerminal.equals("301")){
            GlobalVars.stTerminal = "301";
            String sql1 = "INSERT INTO perif_status (perif,state,date_change) values('terminal','"+GlobalVars.stTerminal+"',UNIX_TIMESTAMP())";
            //System.out.println(sql1);
            try {
                GlobalVars.st.execute(sql1);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        GlobalVars.NomerAb="";
        GlobalVars.GroupId = 0;
        GlobalVars.getCashCode=true;
        tmr = new Timer(1000, updateCursorAction);
        tmr.start();

        System.gc();
    }

    public void update(){

    private Action updateCursorAction = new AbstractAction() {
        public void actionPerformed(ActionEvent e) {
            if(GlobalVars.doBlock){
                if(!GlobalVars.stTerminal.equals("303")){
                    GlobalVars.stTerminal = "303";
                    String sql1 = "INSERT INTO perif_status (perif,state,date_change) values('terminal','"+GlobalVars.stTerminal+"',UNIX_TIMESTAMP())";
                    String sql2 = "UPDATE settings set value='"+GlobalVars.stTerminal+"' WHERE variable='terminal_state'";
                    System.out.println(sql1);
                    System.out.println(sql2);
                    try {
                        GlobalVars.st.execute(sql1);
                    } catch (SQLException e1) {
                        e1.printStackTrace();
                    }
                    try {
                        GlobalVars.st.execute(sql2);
                    } catch (SQLException e1) {
                        e1.printStackTrace();
                    }
                }       
                String sql1 = "UPDATE commands SET status=1, date_execute=UNIX_TIMESTAMP() WHERE id_on_server="+GlobalVars.doCommandId;
                System.out.println(sql1);
                try {
                    GlobalVars.st.execute(sql1);
                } catch (SQLException e1) {
                    e1.printStackTrace();
                }
                if(GlobalVars.jf7==null)
                    try {
                        GlobalVars.jf7= new JF7();
                    } catch (Exception e1) {
                        e1.printStackTrace();
                    }
                try {
                    GlobalVars.jf7.init();
                } catch (Exception e1) {
                    e1.printStackTrace();
                }


                GlobalVars.doBlock=false;
                GlobalVars.doCommandId = 0;
                GlobalVars.jf7.setVisible(true);
                GlobalVars.jf1 = null;
                setVisible(false);
                tmr.stop();
                setVisible(false);
                dispose();
            }
        }
    };

    private static void addComponent(Container container, Component component,int gridx, int gridy, int gridwidth, int gridheight, int anchor,int fill) {
        Insets ins = new Insets(0, 0, 0, 0); 
        GridBagConstraints gbc1 = new GridBagConstraints(gridx, gridy,gridwidth, gridheight, 1.0, 1.0, anchor, fill, ins, 0, 0);
        container.add(component, gbc1);
    }

    public void ActionPerformed(ActionEvent event, int lID,int gId) throws Exception {
        GlobalVars.GroupId = gId;
        if(GlobalVars.jf2==null)GlobalVars.jf2 = new JF2();
        GlobalVars.jf2.init(); 
        GlobalVars.jf2.setVisible(true);
        setVisible(false);
        dispose();
    }
}

这是新的 dump

An application Swing (GUI), a destination a destination information terminal.
The VirtualVM profiler shows that the leakage occurs due to

java.awt.image.DataBufferInt

и

sun.awt.image.ImageRepresentation.setPixels

, the increase of memory occurs during transitions between forms.

The application logic is that there are several forms (JFrame - JF1, JF2 ... JF7). JF1 basic form, pressing the JButtons open other forms, and closes itself, etc. Except JF1 all other forms have buttons <>. In forms there are many JButtons with the pictures, used FancyButton:

public class FancyButton extends JButton {
    private static final long serialVersionUID = 1L;

    public FancyButton(Icon icon, Icon pressed) {
        super(icon);
        setFocusPainted(false);
        //setRolloverEnabled(treue);
        //setRolloverIcon(rollover);
        setPressedIcon(pressed);
        setBorderPainted(false);
        setContentAreaFilled(false);
    }
}

The JButtons on the forms are drawn as follows:

public class JF1 extends JFrame {

    private static final GridBagConstraints gbc;
    public static Timer tmr;

    public JF1() throws Exception{
        setUndecorated(true);
        GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().setFullScreenWindow(this);
        setAlwaysOnTop(true);
        setLayout(new GridBagLayout());
        setTitle("JF1");
    }

    public void init() throws Exception{

        GlobalVars.jf2 = null;
        GlobalVars.jf3 = null;
        GlobalVars.jf4 = null;
        GlobalVars.jf5 = null;
        GlobalVars.jf6 = null;
        GlobalVars.jf7 = null;
        JXPanel contentPane = new JXPanel();
                try {
                ImagePainter ip = new ImagePainter(ImageIO.read(new File("skins/bg.jpg")));
                ip.setFillHorizontal(true);
                ip.setFillVertical(true);
                contentPane.setBackgroundPainter(ip);
             } catch (Exception e) {
                e.printStackTrace();
             }


        Panel p01 = new Panel();
        GridLayout gl01 = new GridLayout(1, 8, 2, 2);
        p01.setLayout(gl01);
        p01.setLocation(200, 300);
        ResultSet rs = GlobalVars.st.executeQuery("select * from last_use_service order by nomer");
        Icon i1;
        Icon i2;
        while (rs.next()){
            final int l = rs.getInt(2);
            i1 = new ImageIcon("skins/oper_logos/" + l + ".png");
            i2 = new ImageIcon("skins/oper_logos/" + l + "_off.png");

            FancyButton jbt = new FancyButton(i1,i2 );
            jbt.setBounds(10, 100, 100, 100);

            jbt.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent event) {
                    tmr.stop();     

                    if(GlobalVars.jf3==null)
                                            GlobalVars.jf3 = new JF3();
                    GlobalVars.jf3.init(); 
                    GlobalVars.jf3.setVisible(true);            // Так открывается новая форма
                    setVisible(false);                              // и закрывается текущая
                    dispose();
                }
            });
            p01.add(jbt);
        }
        rs.close();
        addComponent(panel, p01, 0, 1, 2, 1, GridBagConstraints.WEST,GridBagConstraints.NORTHWEST);
...

The main class which starts first:

public class Main {

    public static class GlobalVars{

        public static String TypeDB = "MySQL";  
        public static Connection DataBase;
        public static Statement st;     

        public static JF1 jf1;          // JFrame
        public static JF2 jf2;          // JFrame
        public static JF3 jf3;          // JFrame
        ...
    }

    public static void main(String[] args) throws Exception {
        if(GlobalVars.TypeDB.equals("MySQL")){
            Class.forName("com.mysql.jdbc.Driver");
            GlobalVars.DataBase = DriverManager.getConnection("jdbc:mysql://localhost:3306/terminal?lc_ctype=UTF8", "root","123");

                if(GlobalVars.jf1==null)
                    GlobalVars.jf1 = new JF1();
        GlobalVars.jf1.init();
        GlobalVars.jf1.setVisible(true);
        }
...
       }

Still in Init method of Forms has a timer which, after a time, opens the main form and closes the current one:

...
tmr = new Timer( s * 1000, updateCursorAction);
tmr.start();
...
private Action updateCursorAction = new AbstractAction() {
        public void actionPerformed(ActionEvent e) {
            if(GlobalVars.jf1==null){
                try {
                    GlobalVars.jf1= new JF1();
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
            }
            tmr.stop();
            try {
                GlobalVars.jf1.init();
            } catch (Exception e1) {
                e1.printStackTrace();
            }
            GlobalVars.jf1.setVisible(true);
            GlobalVars.jf2 = null;
            setVisible(false);
            dispose();      
        }
    };

HEAP DUMP
Please help fix a memory leak.

I had changed all Panel to JPanel and that is code of JF1:

package PlatService;

import java.awt.*;

public class JF1 extends JFrame {
    private static final long serialVersionUID = 1L;
    //private static final Insets insets = new Insets(0, 0, 0, 0);
    private static String[] arrLang = { "rus", "eng", "taj" };
    private static final GridBagConstraints gbc;
    public static Timer tmr;

    static {

    public JF1() throws Exception{
        setUndecorated(true);
        GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().setFullScreenWindow(this);
        setAlwaysOnTop(true);
        setLayout(new GridBagLayout());
        setTitle("JF1");
    }

    public void init() throws Exception{

        GlobalVars.jf2 = null;
        GlobalVars.jf3 = null;
        GlobalVars.jf4 = null;
        GlobalVars.jf5 = null;
        GlobalVars.jf6 = null;
        GlobalVars.jf7 = null;
        JXPanel contentPane = new JXPanel();
        try {
                ImagePainter ip = new ImagePainter(ImageIO.read(new File("skins/bg.jpg")));
                ip.setFillHorizontal(true);
                ip.setFillVertical(true);
                contentPane.setBackgroundPainter(ip);
        } catch (Exception e) {
                e.printStackTrace();
        }
        //setContentPane(contentPane);
        JPanel panel = new JPanel();
        panel.setLayout(new GridBagLayout());
        addComponent(this, panel, 0, 0, 1, 1, GridBagConstraints.CENTER ,GridBagConstraints.BOTH);

        JPanel p0 = new JPanel();
        GridLayout gl0 = new GridLayout(1, 1, 1, 1);
        final JLabel jl = new JLabel(new ImageIcon("skins/logo.png"));
        p0.setLayout(gl0);
        p0.add(jl);
        addComponent(panel, p0, 0, 0, 2, 1, GridBagConstraints.NORTH ,GridBagConstraints.NORTH);


        JPanel p01 = new JPanel();
        GridLayout gl01 = new GridLayout(1, 8, 2, 2);
        p01.setLayout(gl01);
        p01.setLocation(200, 300);
        ResultSet rs = GlobalVars.st.executeQuery("select * from last_use_service order by nomer");
        Icon i1;
        Icon i2;
        while (rs.next()){
            final int l = rs.getInt(2);
            i1 = new ImageIcon("skins/oper_logos/" + l + ".png");
            i2 = new ImageIcon("skins/oper_logos/" + l + "_off.png");
            FancyButton jbt = new FancyButton(i1,i2 );
            jbt.setBounds(10, 100, 100, 100);
            jbt.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent event) {
                    tmr.stop();
                    GlobalVars.OperId = l;
                    GlobalVars.getCashCode=false;
                    if(GlobalVars.jf3==null)GlobalVars.jf3 = new JF3();
                    GlobalVars.jf3.init(); // = new JF3();
                    GlobalVars.jf3.setVisible(true);
                    setVisible(false);
                    dispose();
                }
            });
            p01.add(jbt);
        }
        rs.close();
        addComponent(panel, p01, 0, 1, 2, 1, GridBagConstraints.WEST,GridBagConstraints.NORTHWEST);

        if (GlobalVars.LangId < 0 || GlobalVars.LangId > 2)GlobalVars.LangId = 0;

        String sql = "SELECT * FROM OpGroup WHERE parent=0 order by enable desc, order_n";
        PreparedStatement psmnt = GlobalVars.DataBase.prepareStatement(sql);
        ResultSet rs2 = psmnt.executeQuery();

        //rs = GlobalVars.st.executeQuery();
        JPanel p = new JPanel();
        GridLayout gl = new GridLayout(0, 2, 2, 2);
        p.setLayout(gl);
        p.setSize(300, 400);
        p.setLocation(200, 300);        
        while (rs2.next()){
            final int l = rs2.getInt(2);
            i1 = new ImageIcon("skins/"+ arrLang[GlobalVars.LangId]+"/services/" + l + ".png");
            i2 = new ImageIcon("skins/"+ arrLang[GlobalVars.LangId]+"/services/" + l + "_off.png");
            FancyButton jbt = new FancyButton(i1,i2);
            jbt.setBounds(10, 100, 100, 100);
            if(rs2.getInt("enable")==1){
                jbt.setEnabled(true);
            }else{
                jbt.setEnabled(false);
            }
            jbt.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent event) {
                    GlobalVars.getCashCode=false;
                    try {
                        tmr.stop();
                        ActionPerformed(event, GlobalVars.LangId, l);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
            p.add(jbt);
        }
        addComponent(panel, p, 0, 2, 1, 1, GridBagConstraints.NORTH,GridBagConstraints.NORTH);
        rs2.close();
        JPanel p1 = new JPanel();
        GridLayout gl1 = new GridLayout(5, 1, 5, 5);
        // setLayout(new GridLayout(3, 4, 2, 2));
        p1.setLayout(gl1);
        // p2.setSize(300, 400);
        // p2.setLocation(200, 300);

        for (int i = 0; i < arrLang.length; i++) {
            final int l = i;
            i1 = new ImageIcon("skins/button_" + arrLang[i] + ".png");
            i2 = new ImageIcon("skins/button_" + arrLang[i] + "_off.png");
            FancyButton jbt = new FancyButton(i1, i2);
            jbt.setBounds(10, 100, 100, 100);
            //if (i == GlobalVars.LangId) {jbt.setEnabled(false);}
            jbt.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent event) {
                    //Play.stop();
                    GlobalVars.LangId = l;
                    GlobalVars.getCashCode=false;
                    GlobalVars.jf1 = null;
                    try {
                        GlobalVars.jf1 = new JF1();
                    } catch (Exception e1) {
                        e1.printStackTrace();
                    }
                    try {
                        GlobalVars.jf1.init();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    tmr.stop();
                    GlobalVars.jf1.setVisible(true);
                    setVisible(false);
                }
            });
            p1.add(jbt);
        }
        i1 = new ImageIcon("skins/" + arrLang[GlobalVars.LangId] + "/services/button_help.png");
        i2 = new ImageIcon("skins/" + arrLang[GlobalVars.LangId] + "/services/button_help_off.png");
        FancyButton jbt_help = new FancyButton(i1,i2);
        jbt_help.setBounds(10, 100, 100, 100);
        jbt_help.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                tmr.stop();
                GlobalVars.getCashCode=false;
                GlobalVars.jf1 = null;
                try {
                    GlobalVars.jf1 = new JF1();
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
                try {
                    GlobalVars.jf1.init();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                GlobalVars.jf1.setVisible(true);
                setVisible(false);
            }
        });
        p1.add(jbt_help);
        i1 = new ImageIcon("skins/" + arrLang[GlobalVars.LangId] + "/services/button_about.png");
        i2 = new ImageIcon("skins/" + arrLang[GlobalVars.LangId] + "/services/button_about_off.png");
        FancyButton jbt_about = new FancyButton(i1,i2);
        jbt_about.setBounds(10, 100, 100, 100);

        p1.add(jbt_about);
        addComponent(panel, p1, 1, 2, 1, 1, GridBagConstraints.EAST,GridBagConstraints.EAST);

        JPanel p011 = new JPanel();
        GridLayout gl011 = new GridLayout( 1, 1, 1, 1);
        gl011.setVgap(1);
        JLabel jl12 = new JLabel("<html><hr></html>", JLabel.LEFT);
        jl12.setAlignmentX(TOP_ALIGNMENT);
        jl12.setBackground(Color.red);
        p011.setLayout(gl011);
        p011.add(jl12);
        p011.setSize(10, 90);
        addComponent(panel, p011, 0, 3, 4, 1, GridBagConstraints.WEST, GridBagConstraints.NORTH);


        JPanel p0112 = new JPanel();
        GridLayout gl0112 = new GridLayout( 1, 1, 1, 1);
        gl0112.setVgap(1);
        JLabel jl122 = new JLabel("<html><hr><H2>"+GlobalVars.StatusMessage[GlobalVars.LangId]+"</H2></html>", JLabel.CENTER);
        jl122.setAlignmentX(TOP_ALIGNMENT);
        p0112.setLayout(gl0112);
        p0112.add(jl122);
        p0112.setSize(10, 90);

        addComponent(this, p0112, 0, 5, 5, 1, GridBagConstraints.SOUTH, GridBagConstraints.BOTH);

        if(!GlobalVars.stTerminal.equals("301")){
            GlobalVars.stTerminal = "301";
            String sql1 = "INSERT INTO perif_status (perif,state,date_change) values('terminal','"+GlobalVars.stTerminal+"',UNIX_TIMESTAMP())";
            //System.out.println(sql1);
            try {
                GlobalVars.st.execute(sql1);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        GlobalVars.NomerAb="";
        GlobalVars.GroupId = 0;
        GlobalVars.getCashCode=true;
        tmr = new Timer(1000, updateCursorAction);
        tmr.start();

        System.gc();
    }

    public void update(){

    private Action updateCursorAction = new AbstractAction() {
        public void actionPerformed(ActionEvent e) {
            if(GlobalVars.doBlock){
                if(!GlobalVars.stTerminal.equals("303")){
                    GlobalVars.stTerminal = "303";
                    String sql1 = "INSERT INTO perif_status (perif,state,date_change) values('terminal','"+GlobalVars.stTerminal+"',UNIX_TIMESTAMP())";
                    String sql2 = "UPDATE settings set value='"+GlobalVars.stTerminal+"' WHERE variable='terminal_state'";
                    System.out.println(sql1);
                    System.out.println(sql2);
                    try {
                        GlobalVars.st.execute(sql1);
                    } catch (SQLException e1) {
                        e1.printStackTrace();
                    }
                    try {
                        GlobalVars.st.execute(sql2);
                    } catch (SQLException e1) {
                        e1.printStackTrace();
                    }
                }       
                String sql1 = "UPDATE commands SET status=1, date_execute=UNIX_TIMESTAMP() WHERE id_on_server="+GlobalVars.doCommandId;
                System.out.println(sql1);
                try {
                    GlobalVars.st.execute(sql1);
                } catch (SQLException e1) {
                    e1.printStackTrace();
                }
                if(GlobalVars.jf7==null)
                    try {
                        GlobalVars.jf7= new JF7();
                    } catch (Exception e1) {
                        e1.printStackTrace();
                    }
                try {
                    GlobalVars.jf7.init();
                } catch (Exception e1) {
                    e1.printStackTrace();
                }


                GlobalVars.doBlock=false;
                GlobalVars.doCommandId = 0;
                GlobalVars.jf7.setVisible(true);
                GlobalVars.jf1 = null;
                setVisible(false);
                tmr.stop();
                setVisible(false);
                dispose();
            }
        }
    };

    private static void addComponent(Container container, Component component,int gridx, int gridy, int gridwidth, int gridheight, int anchor,int fill) {
        Insets ins = new Insets(0, 0, 0, 0); 
        GridBagConstraints gbc1 = new GridBagConstraints(gridx, gridy,gridwidth, gridheight, 1.0, 1.0, anchor, fill, ins, 0, 0);
        container.add(component, gbc1);
    }

    public void ActionPerformed(ActionEvent event, int lID,int gId) throws Exception {
        GlobalVars.GroupId = gId;
        if(GlobalVars.jf2==null)GlobalVars.jf2 = new JF2();
        GlobalVars.jf2.init(); 
        GlobalVars.jf2.setVisible(true);
        setVisible(false);
        dispose();
    }
}

And thats new dump

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不语却知心 2024-12-19 05:53:39

您确实存在泄漏,但仅查看加载的类的数量并不能帮助您找出泄漏是什么。

如果您在 JProfiler 中加载快照(免责声明:我的公司开发 JProfiler )并查看最大的对象视图,您可以看到使用的内存是由于多个 JF1以及属于这些帧的面板实例的双缓冲造成的帧。

在此处输入图像描述

您的问题是 JF1 框架被隐藏但未处理。对 GC 根的搜索显示,所有 3 个不可见框架都包含在 java.awt.Window.allWindows 中,如果调用 dispose() 则不会出现这种情况。您在事件调度线程之外调用了很多代码。例如,您不应该从计时器线程调用 setVisible()。尝试打印出 JF1 框架的创建以及对其 dispose 方法的调用,并检查它们不匹配的位置。

在此处输入图像描述

You do have a leak, but just looking at the number of loaded classes will not help you to find out what it is.

If you load your snapshot in JProfiler (disclaimer: my company develops JProfiler) and look at the biggest objects view, you can see that used memory is due to the double buffering of multiple JF1 frames and the panel instances that belong to those frames.

enter image description here

Your problem is that the JF1 frames are hidden but not disposed. A search for GC roots shows that all 3 invisible frames are contained in java.awt.Window.allWindows which cannot the case if dispose() is called. You call a lot of code outside the event dispatch thread. For example you should not call setVisible() from the timer thread. Try printing out the creation of JF1 frames and the call to their dispose methods and check where the do not they match.

enter image description here

惟欲睡 2024-12-19 05:53:39

您创建了许多 顶级容器,其中 JComponents 或其中的 Images ,以及这些这种形式的对象永远不会消失在JVMUsed_Memory中,你必须清理未使用的顶级容器的内容,

更好的是

仅创建 JFrame 一次,对于另一个弹出窗口,仅创建一个 JDialog/JWindow 放在此处 JPanel,通过删除 重新使用此容器>JComponents 来自JPanel

JPanel.removeAll();

DefaultCloseOperation 将为

JDialog#setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE)

或者您可以设置

JDialog#setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE) 然后你只能调用

JDialog#setVisible(false / true)

EDIT

,并且必须在finally块中关闭所有 JDBC ResultSet、Statement、PreparedStatement,因为这些对象也从未从 JVM UseMemory 中消失

you create lots of Top-level Containers, with JComponents or Images inside them, and these Objects in this form never gone for JVM Used_Memory, you have to clean-up contents of un-used Top-level Containers,

better would be

create JFrame only once, and for another popup windows create only one JDialog/JWindow put here JPanel, re-use this Container by removing JComponents from JPanel,

JPanel.removeAll();

DefaultCloseOperation would be

JDialog#setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE)

or you can set

JDialog#setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE) and then you can call only

JDialog#setVisible(false / true)

EDIT

and you have to close all JDBC ResultSet, Statement, PreparedStatement in finally block, because these Object never gone from JVM UsedMemory too

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文