-
Bug
-
Resolution: Fixed
-
P4
-
1.4.0
-
02
-
x86
-
windows_nt
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-2047479 | 1.4.1 | Scott Violet | P4 | Resolved | Fixed | hopper |
Name: nt126004 Date: 09/25/2001
java version "1.4.0-beta2"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta2-b77)
Java HotSpot(TM) Client VM (build 1.4.0-beta2-b77, mixed mode)
We have a large application that adds and removes many tab panels to a
JTabbedPane while it is running. The tab panels have one or more JTables on
them. Everytime a panel is add a AWTEventMulticaster and JViewport$ViewListener
are created for the JTableHeader in the view for the viewport. These objects
accumulate over time. You can see the behavior by running Optimizeit on the
attached program.
-Push button1 which will add another tab panel with a JTable on it
-Push button2 which removes the panel again
-Garbage collect and set a mark in Optimizeit
-Push button1 and then button2 again
-Garbage collect and look at the diff in classes created since the mark
-There should be 1 AWTEventMulticaster object and 1 JViewport$ViewListener
object. Do the above again and more of these objects will be created
and not garbage collected.
It looks like the viewport creates a new viewlistner everytime a panel with a
jtable is added but it doesn't free up the viewlistener when a tab is removed.
Here is the sample code:
package ztest;
/**
*/
public class TabPaneMemLeak extends javax.swing.JPanel {
IvjEventHandler ivjEventHandler = new IvjEventHandler();
private javax.swing.JButton ivjJButton1 = null;
private javax.swing.JPanel ivjJPanel1 = null;
private javax.swing.JScrollPane ivjJScrollPane1 = null;
private javax.swing.JTabbedPane ivjJTabbedPane1 = null;
private javax.swing.JPanel ivjPage = null;
private javax.swing.JTable ivjScrollPaneTable = null;
class IvjEventHandler implements java.awt.event.ActionListener {
public void actionPerformed(java.awt.event.ActionEvent e) {
if (e.getSource() == TabPaneMemLeak.this.getJButton1())
connEtoC1(e);
if (e.getSource() == TabPaneMemLeak.this.getJButton2())
connEtoC2(e);
};
};
private javax.swing.JButton ivjJButton2 = null;
/**
* TabPaneMemLeak constructor comment.
*/
public TabPaneMemLeak() {
super();
initialize();
}
/**
* main entrypoint - starts the part when it is run as an application
* @param args java.lang.String[]
*/
public static void main(java.lang.String[] args) {
try {
javax.swing.JFrame frame = new javax.swing.JFrame();
TabPaneMemLeak aTabPaneMemLeak;
aTabPaneMemLeak = new TabPaneMemLeak();
frame.setContentPane(aTabPaneMemLeak);
frame.setSize(aTabPaneMemLeak.getSize());
frame.addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent e)
{
System.exit(0);
};
});
frame.show();
java.awt.Insets insets = frame.getInsets();
frame.setSize(frame.getWidth() + insets.left + insets.right,
frame.getHeight() + insets.top + insets.bottom);
frame.setVisible(true);
} catch (Throwable exception) {
System.err.println("Exception occurred in main() of
javax.swing.JPanel");
exception.printStackTrace(System.out);
}
}
/**
* connEtoC1: (JButton1.action.actionPerformed(java.awt.event.ActionEvent) -->
TabPaneMemLeak.jButton1_ActionPerformed(Ljava.awt.event.ActionEvent;)V)
* @param arg1 java.awt.event.ActionEvent
*/
private void connEtoC1(java.awt.event.ActionEvent arg1) {
try {
this.jButton1_ActionPerformed(arg1);
} catch (java.lang.Throwable ivjExc) {
handleException(ivjExc);
}
}
/**
* connEtoC2: (JButton2.action.actionPerformed(java.awt.event.ActionEvent) -->
TabPaneMemLeak.jButton2_ActionPerformed(Ljava.awt.event.ActionEvent;)V)
* @param arg1 java.awt.event.ActionEvent
*/
private void connEtoC2(java.awt.event.ActionEvent arg1) {
try {
this.jButton2_ActionPerformed(arg1);
} catch (java.lang.Throwable ivjExc) {
handleException(ivjExc);
}
}
/**
* Return the JButton1 property value.
* @return javax.swing.JButton
*/
private javax.swing.JButton getJButton1() {
if (ivjJButton1 == null) {
try {
ivjJButton1 = new javax.swing.JButton();
ivjJButton1.setName("JButton1");
ivjJButton1.setText("JButton1");
ivjJButton1.setBounds(151, 167, 85, 25);
} catch (java.lang.Throwable ivjExc) {
handleException(ivjExc);
}
}
return ivjJButton1;
}
/**
* Return the JButton2 property value.
* @return javax.swing.JButton
*/
private javax.swing.JButton getJButton2() {
if (ivjJButton2 == null) {
try {
ivjJButton2 = new javax.swing.JButton();
ivjJButton2.setName("JButton2");
ivjJButton2.setText("JButton2");
ivjJButton2.setBounds(153, 242, 85, 25);
} catch (java.lang.Throwable ivjExc) {
handleException(ivjExc);
}
}
return ivjJButton2;
}
/**
* Return the JPanel1 property value.
* @return javax.swing.JPanel
*/
private javax.swing.JPanel getJPanel1() {
if (ivjJPanel1 == null) {
try {
ivjJPanel1 = new javax.swing.JPanel();
ivjJPanel1.setName("JPanel1");
ivjJPanel1.setLayout(new java.awt.BorderLayout());
ivjJPanel1.setBounds(575, 215, 160, 120);
getJPanel1().add(getJScrollPane1(), "Center");
} catch (java.lang.Throwable ivjExc) {
handleException(ivjExc);
}
}
return ivjJPanel1;
}
/**
* Return the JScrollPane1 property value.
* @return javax.swing.JScrollPane
*/
private javax.swing.JScrollPane getJScrollPane1() {
if (ivjJScrollPane1 == null) {
try {
ivjJScrollPane1 = new javax.swing.JScrollPane();
ivjJScrollPane1.setName("JScrollPane1");
ivjJScrollPane1.setVerticalScrollBarPolicy(javax.swing.JScrollPane.VERTICAL_SCRO
LLBAR_ALWAYS);
ivjJScrollPane1.setHorizontalScrollBarPolicy(javax.swing.JScrollPane.HORIZONTAL_
SCROLLBAR_ALWAYS);
getJScrollPane1().setViewportView(getScrollPaneTable());
} catch (java.lang.Throwable ivjExc) {
handleException(ivjExc);
}
}
return ivjJScrollPane1;
}
/**
* Return the JTabbedPane1 property value.
* @return javax.swing.JTabbedPane
*/
private javax.swing.JTabbedPane getJTabbedPane1() {
if (ivjJTabbedPane1 == null) {
try {
ivjJTabbedPane1 = new javax.swing.JTabbedPane();
ivjJTabbedPane1.setName("JTabbedPane1");
ivjJTabbedPane1.insertTab("Page", null, getPage(), null,
0);
} catch (java.lang.Throwable ivjExc) {
handleException(ivjExc);
}
}
return ivjJTabbedPane1;
}
/**
* Return the Page property value.
* @return javax.swing.JPanel
*/
private javax.swing.JPanel getPage() {
if (ivjPage == null) {
try {
ivjPage = new javax.swing.JPanel();
ivjPage.setName("Page");
ivjPage.setLayout(null);
getPage().add(getJButton1(), getJButton1().getName());
getPage().add(getJButton2(), getJButton2().getName());
} catch (java.lang.Throwable ivjExc) {
handleException(ivjExc);
}
}
return ivjPage;
}
/**
* Return the ScrollPaneTable property value.
* @return javax.swing.JTable
*/
private javax.swing.JTable getScrollPaneTable() {
if (ivjScrollPaneTable == null) {
try {
ivjScrollPaneTable = new javax.swing.JTable();
ivjScrollPaneTable.setName("ScrollPaneTable");
getJScrollPane1().setColumnHeaderView(ivjScrollPaneTable.getTableHeader());
ivjScrollPaneTable.setBounds(0, 0, 200, 200);
} catch (java.lang.Throwable ivjExc) {
handleException(ivjExc);
}
}
return ivjScrollPaneTable;
}
/**
* Called whenever the part throws an exception.
* @param exception java.lang.Throwable
*/
private void handleException(java.lang.Throwable exception) {
exception.printStackTrace(System.out);
}
/**
* Initializes connections
* @exception java.lang.Exception The exception description.
*/
private void initConnections() throws java.lang.Exception {
getJButton1().addActionListener(ivjEventHandler);
getJButton2().addActionListener(ivjEventHandler);
}
/**
* Initialize the class.
*/
private void initialize() {
try {
setName("TabPaneMemLeak");
setLayout(new java.awt.BorderLayout());
setSize(391, 408);
add(getJTabbedPane1(), "Center");
initConnections();
} catch (java.lang.Throwable ivjExc) {
handleException(ivjExc);
}
}
/**
* Comment
*/
public void jButton1_ActionPerformed(java.awt.event.ActionEvent actionEvent)
{
getJTabbedPane1().addTab("Test", getJPanel1());
return;
}
/**
* Comment
*/
public void jButton2_ActionPerformed(java.awt.event.ActionEvent actionEvent) {
getJTabbedPane1().remove(getJPanel1());
return;
}
}
(Review ID: 132354)
======================================================================
- backported by
-
JDK-2047479 Memory leak of AWTEventMulticaster
-
- Resolved
-