Swing中的内存泄漏

达勒:

应用程序Swing(GUI),目的地,目的地信息终端。VirtualVM事件探查器显示发生泄漏是由于

java.awt.image.DataBufferInt

sun.awt.image.ImageRepresentation.setPixels

,内存的增加发生在表单之间的转换期间。

应用逻辑是有几种形式(JFrame-JF1,JF2 ... JF7)。JF1基本表单,按下JButton可以打开其他表单,然后关闭自身,依此类推。除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();      
        }
    };

HEAP DUMP请帮助修复内存泄漏。

我已经将所有Panel更改为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();
    }
}

那就是新的转储

英戈·凯格尔:

您确实有泄漏,但是仅查看已加载类的数量并不能帮助您了解它的含义。

如果将快照加载到JProfiler中(免责声明:我的公司开发JProfiler)并查看最大的对象视图,则可以看到使用的内存是由于多个JF1框架和属于这些框架的面板实例的双重缓冲所致

在此处输入图片说明

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

在此处输入图片说明

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章