Swing 中的内存泄漏
一个应用程序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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您确实存在泄漏,但仅查看加载的类的数量并不能帮助您找出泄漏是什么。
如果您在 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.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 injava.awt.Window.allWindows
which cannot the case ifdispose()
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.您创建了许多 顶级容器,其中 JComponents 或其中的
Images
,以及这些这种形式的对象
永远不会消失在JVMUsed_Memory
中,你必须清理未使用的顶级容器
的内容,更好的是
仅创建
JFrame
一次,对于另一个弹出窗口,仅创建一个JDialog/JWindow
放在此处JPanel
,通过删除重新使用此容器>JComponents
来自JPanel
,DefaultCloseOperation 将为
JDialog#setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE)
或者您可以设置
JDialog#setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE)
然后你只能调用EDIT
,并且必须在finally块中关闭所有 JDBC ResultSet、Statement、PreparedStatement,因为这些对象也从未从 JVM UseMemory 中消失
you create lots of Top-level Containers, with JComponents or
Images
inside them, and theseObjects
in this form never gone forJVM Used_Memory
, you have to clean-up contents of un-usedTop-level Containers
,better would be
create
JFrame
only once, and for another popup windows create only oneJDialog/JWindow
put hereJPanel
, re-use this Container by removingJComponents
fromJPanel
,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 onlyEDIT
and you have to close all JDBC ResultSet, Statement, PreparedStatement in finally block, because these Object never gone from JVM UsedMemory too