Утечка памяти в 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);
        }
...
       }

Еще в Init методе Forms есть таймер, который через некоторое время открывает главную форму и закрывает текущую:

...
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("
", 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("

"+GlobalVars.StatusMessage[GlobalVars.LangId]+"

", 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(); } }

И это новый дамп

5
задан Daler 28 October 2011 в 09:59
поделиться