-
Bug
-
Resolution: Not an Issue
-
P3
-
None
-
1.3.0, 1.3.1, 1.4.0, 1.4.2, 5.0
-
x86, sparc
-
linux, solaris_7, solaris_8, windows_nt, windows_2003
FULL PRODUCT VERSION :
J@SDK 1.4.2
ADDITIONAL OS VERSION INFORMATION :
Windows 2000
A DESCRIPTION OF THE PROBLEM :
I have an Action object whose doAction() function creates multiple JDialogs in succession (reusing the reference each time). If this Action Object's doAction() function is called from a popup or pulldown menu, the memory for all the JDialogs is never released. If this exact same call is made from the startup main, memory reclamation proceeds as expected.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
I've included three simple classes. 'KevAppWindow' (a Jframe) which instantiates the action ('KevDFAction')and sets up the popup menu. The 'KevDFAction's doAction() creates many 'KevDialog's (which are just JDialogs which take up memory) while reusing a single reference to the dialogs. Compile all three, and place in the same folder. Run 'KevAppWindow's main function which will show a blank window, then right-click within the frame to get the popup. Select the only choice "KevAction" and the output will report dialogs being created, and never finalized. You will quickly run out of memory.
To see the same action perform proper garbage collection, uncomment line 3 of the 'KevAppWindow's main function. This will make the same call on startup without going thru the popup.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Starting application C:\EDNA\EdnaProject\kevin\KevAppWindow.class
Command line: "C:\j2sdk1.4.2_06\jre\bin\java.exe" -classpath C:\EDNA\EdnaProject kevin.KevAppWindow
The current directory is: C:\EDNA\EdnaProject\kevin
Kev Action
*******Instantiating KevDialog: count= 1
*******Instantiating KevDialog: count= 2
*******Finalizing KevDialog: count= 1
*******Instantiating KevDialog: count= 2
*******Instantiating KevDialog: count= 3
*******Instantiating KevDialog: count= 4
*******Finalizing KevDialog: count= 3
*******Instantiating KevDialog: count= 4
*******Instantiating KevDialog: count= 5
*******Finalizing KevDialog: count= 4
*******Instantiating KevDialog: count= 5
*******Instantiating KevDialog: count= 6
*******Finalizing KevDialog: count= 5
*******Instantiating KevDialog: count= 6
*******Instantiating KevDialog: count= 7
*******Finalizing KevDialog: count= 6
*******Instantiating KevDialog: count= 7
*******Instantiating KevDialog: count= 8
*******Finalizing KevDialog: count= 7
*******Finalizing KevDialog: count= 6
*******Finalizing KevDialog: count= 5
*******Finalizing KevDialog: count= 4
*******Finalizing KevDialog: count= 3
*******Finalizing KevDialog: count= 2
...
...
...contiunues to completion
ACTUAL -
Starting application C:\EDNA\EdnaProject\kevin\KevAppWindow.class
Command line: "C:\j2sdk1.4.2_06\jre\bin\java.exe" -classpath C:\EDNA\EdnaProject kevin.KevAppWindow
The current directory is: C:\EDNA\EdnaProject\kevin
Kev Action
*******Instantiating KevDialog: count= 1
*******Instantiating KevDialog: count= 2
*******Instantiating KevDialog: count= 3
*******Instantiating KevDialog: count= 4
*******Instantiating KevDialog: count= 5
*******Instantiating KevDialog: count= 6
*******Instantiating KevDialog: count= 7
*******Instantiating KevDialog: count= 8
*******Instantiating KevDialog: count= 9
...
...
...
*******Instantiating KevDialog: count= 625
*******Instantiating KevDialog: count= 626
*******Instantiating KevDialog: count= 627
*******Instantiating KevDialog: count= 628
*******Instantiating KevDialog: count= 629
*******Instantiating KevDialog: count= 630
*******Instantiating KevDialog: count= 631
*******Instantiating KevDialog: count= 632
*******Instantiating KevDialog: count= 633
*******Instantiating KevDialog: count= 634
*******Instantiating KevDialog: count= 635
*******Instantiating KevDialog: count= 636
*******Instantiating KevDialog: count= 637
*******Instantiating KevDialog: count= 638
java.lang.OutOfMemoryError
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Starting application C:\EDNA\EdnaProject\kevin\KevAppWindow.class
Command line: "C:\j2sdk1.4.2_06\jre\bin\java.exe" -classpath C:\EDNA\EdnaProject kevin.KevAppWindow
The current directory is: C:\EDNA\EdnaProject\kevin
Kev Action
*******Instantiating KevDialog: count= 1
*******Instantiating KevDialog: count= 2
*******Instantiating KevDialog: count= 3
*******Instantiating KevDialog: count= 4
*******Instantiating KevDialog: count= 5
*******Instantiating KevDialog: count= 6
*******Instantiating KevDialog: count= 7
*******Instantiating KevDialog: count= 8
*******Instantiating KevDialog: count= 9
...
...
...
*******Instantiating KevDialog: count= 625
*******Instantiating KevDialog: count= 626
*******Instantiating KevDialog: count= 627
*******Instantiating KevDialog: count= 628
*******Instantiating KevDialog: count= 629
*******Instantiating KevDialog: count= 630
*******Instantiating KevDialog: count= 631
*******Instantiating KevDialog: count= 632
*******Instantiating KevDialog: count= 633
*******Instantiating KevDialog: count= 634
*******Instantiating KevDialog: count= 635
*******Instantiating KevDialog: count= 636
*******Instantiating KevDialog: count= 637
*******Instantiating KevDialog: count= 638
java.lang.OutOfMemoryError
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
FILE 1:
package kevin;
import java.awt.event.*;
import javax.swing.*;
/**
* This class developed in stripped down version to show the JAVA memory leak.
* If the call to kevDFAction.doAction() is made from "main()" (uncomment the third line in "main()")
* we can see the KevDialog's being instantiated and finalized (reclaimed). But, if this same call
* to kevDFAction.doAction() is made from a popup (right-click within the frame), the memory is never
* reclaimed, and in fact results in a java.lang.OutOfMemoryError very quickly.
*/
public class KevAppWindow extends JFrame implements MouseListener {
public static KevDFAction kevDFAction;
private JPopupMenu popupMenu;
public static final boolean ENABLED = true;
public static final boolean DISABLED = false;
public KevAppWindow (String title) {
super (title);
addMouseListener (this);
setSize(620, 220);
kevDFAction = new KevDFAction (ENABLED);
popupMenu = new JPopupMenu();
popupMenu.add (kevDFAction); //in search of the memory leak
}
public void mousePressed(MouseEvent e) { //kaw is a mouseListener
doPopup(e);
}
public void mouseClicked(MouseEvent e) {
doPopup(e);
}
public void mouseReleased(MouseEvent e) {
doPopup(e);
}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
private void doPopup(MouseEvent e) {
if (e.isPopupTrigger()) {
popupMenu.show(this, e.getX(), e.getY()); //x & y of position of mouse during rt-click
}
}
public static void main (String args[]) {
KevAppWindow kaw = new KevAppWindow ("To show Java Memory Leak, right click for popup and Select!");
kaw.setVisible (true);
//kaw.kevDFAction.doAction(); //no memory leak if run from here, but call this from a popup and she runs out of memory right away
}
}
FILE2:
package kevin;
import javax.swing.*;
import java.awt.event.*;
public class KevDFAction extends AbstractAction {
public KevDFAction(boolean enabled ) {
super ("Kev Action");
}
public void doAction () {
System.out.println("Kev Action");
for (int j = 0; j < 10000; j++) {
KevDialog kDialog = new KevDialog();
kDialog.dispose(); //don't need this, but just to make the point
}
}
public void actionPerformed(ActionEvent e)
{
//System.out.println("Action Performed");
doAction();
}
public static void main (String[] args) { //in search of the memory leak
KevDFAction kAction = new KevDFAction(true);
kAction.doAction();
}
}
FILE 3:
package kevin;
import javax.swing.*;
import java.lang.*;
import java.awt.*;
public class KevDialog extends JDialog {
private String[] options = new String[1000];
private static int dialogCount;
public KevDialog() {
++dialogCount;
System.out.println("*******Instantiating KevDialog: count= " + dialogCount);
for (int i = 0; i < 1000; i++) {
options[i] = new String("OPTION_Take up some space_" + i);
}
}
public void finalize() throws Throwable {
--dialogCount;
System.out.println("*******Finalizing KevDialog: count= " + dialogCount);
super.finalize();
}
public static void main (String[] args) {
for (int j = 0; j < 10000; j++) {
KevDialog kDialog = new KevDialog();
kDialog.dispose();
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
I have to make all my large jobs standalone programs as I can't incorporate them into a menu system. Very user unfriendly.
J@SDK 1.4.2
ADDITIONAL OS VERSION INFORMATION :
Windows 2000
A DESCRIPTION OF THE PROBLEM :
I have an Action object whose doAction() function creates multiple JDialogs in succession (reusing the reference each time). If this Action Object's doAction() function is called from a popup or pulldown menu, the memory for all the JDialogs is never released. If this exact same call is made from the startup main, memory reclamation proceeds as expected.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
I've included three simple classes. 'KevAppWindow' (a Jframe) which instantiates the action ('KevDFAction')and sets up the popup menu. The 'KevDFAction's doAction() creates many 'KevDialog's (which are just JDialogs which take up memory) while reusing a single reference to the dialogs. Compile all three, and place in the same folder. Run 'KevAppWindow's main function which will show a blank window, then right-click within the frame to get the popup. Select the only choice "KevAction" and the output will report dialogs being created, and never finalized. You will quickly run out of memory.
To see the same action perform proper garbage collection, uncomment line 3 of the 'KevAppWindow's main function. This will make the same call on startup without going thru the popup.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Starting application C:\EDNA\EdnaProject\kevin\KevAppWindow.class
Command line: "C:\j2sdk1.4.2_06\jre\bin\java.exe" -classpath C:\EDNA\EdnaProject kevin.KevAppWindow
The current directory is: C:\EDNA\EdnaProject\kevin
Kev Action
*******Instantiating KevDialog: count= 1
*******Instantiating KevDialog: count= 2
*******Finalizing KevDialog: count= 1
*******Instantiating KevDialog: count= 2
*******Instantiating KevDialog: count= 3
*******Instantiating KevDialog: count= 4
*******Finalizing KevDialog: count= 3
*******Instantiating KevDialog: count= 4
*******Instantiating KevDialog: count= 5
*******Finalizing KevDialog: count= 4
*******Instantiating KevDialog: count= 5
*******Instantiating KevDialog: count= 6
*******Finalizing KevDialog: count= 5
*******Instantiating KevDialog: count= 6
*******Instantiating KevDialog: count= 7
*******Finalizing KevDialog: count= 6
*******Instantiating KevDialog: count= 7
*******Instantiating KevDialog: count= 8
*******Finalizing KevDialog: count= 7
*******Finalizing KevDialog: count= 6
*******Finalizing KevDialog: count= 5
*******Finalizing KevDialog: count= 4
*******Finalizing KevDialog: count= 3
*******Finalizing KevDialog: count= 2
...
...
...contiunues to completion
ACTUAL -
Starting application C:\EDNA\EdnaProject\kevin\KevAppWindow.class
Command line: "C:\j2sdk1.4.2_06\jre\bin\java.exe" -classpath C:\EDNA\EdnaProject kevin.KevAppWindow
The current directory is: C:\EDNA\EdnaProject\kevin
Kev Action
*******Instantiating KevDialog: count= 1
*******Instantiating KevDialog: count= 2
*******Instantiating KevDialog: count= 3
*******Instantiating KevDialog: count= 4
*******Instantiating KevDialog: count= 5
*******Instantiating KevDialog: count= 6
*******Instantiating KevDialog: count= 7
*******Instantiating KevDialog: count= 8
*******Instantiating KevDialog: count= 9
...
...
...
*******Instantiating KevDialog: count= 625
*******Instantiating KevDialog: count= 626
*******Instantiating KevDialog: count= 627
*******Instantiating KevDialog: count= 628
*******Instantiating KevDialog: count= 629
*******Instantiating KevDialog: count= 630
*******Instantiating KevDialog: count= 631
*******Instantiating KevDialog: count= 632
*******Instantiating KevDialog: count= 633
*******Instantiating KevDialog: count= 634
*******Instantiating KevDialog: count= 635
*******Instantiating KevDialog: count= 636
*******Instantiating KevDialog: count= 637
*******Instantiating KevDialog: count= 638
java.lang.OutOfMemoryError
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Starting application C:\EDNA\EdnaProject\kevin\KevAppWindow.class
Command line: "C:\j2sdk1.4.2_06\jre\bin\java.exe" -classpath C:\EDNA\EdnaProject kevin.KevAppWindow
The current directory is: C:\EDNA\EdnaProject\kevin
Kev Action
*******Instantiating KevDialog: count= 1
*******Instantiating KevDialog: count= 2
*******Instantiating KevDialog: count= 3
*******Instantiating KevDialog: count= 4
*******Instantiating KevDialog: count= 5
*******Instantiating KevDialog: count= 6
*******Instantiating KevDialog: count= 7
*******Instantiating KevDialog: count= 8
*******Instantiating KevDialog: count= 9
...
...
...
*******Instantiating KevDialog: count= 625
*******Instantiating KevDialog: count= 626
*******Instantiating KevDialog: count= 627
*******Instantiating KevDialog: count= 628
*******Instantiating KevDialog: count= 629
*******Instantiating KevDialog: count= 630
*******Instantiating KevDialog: count= 631
*******Instantiating KevDialog: count= 632
*******Instantiating KevDialog: count= 633
*******Instantiating KevDialog: count= 634
*******Instantiating KevDialog: count= 635
*******Instantiating KevDialog: count= 636
*******Instantiating KevDialog: count= 637
*******Instantiating KevDialog: count= 638
java.lang.OutOfMemoryError
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
FILE 1:
package kevin;
import java.awt.event.*;
import javax.swing.*;
/**
* This class developed in stripped down version to show the JAVA memory leak.
* If the call to kevDFAction.doAction() is made from "main()" (uncomment the third line in "main()")
* we can see the KevDialog's being instantiated and finalized (reclaimed). But, if this same call
* to kevDFAction.doAction() is made from a popup (right-click within the frame), the memory is never
* reclaimed, and in fact results in a java.lang.OutOfMemoryError very quickly.
*/
public class KevAppWindow extends JFrame implements MouseListener {
public static KevDFAction kevDFAction;
private JPopupMenu popupMenu;
public static final boolean ENABLED = true;
public static final boolean DISABLED = false;
public KevAppWindow (String title) {
super (title);
addMouseListener (this);
setSize(620, 220);
kevDFAction = new KevDFAction (ENABLED);
popupMenu = new JPopupMenu();
popupMenu.add (kevDFAction); //in search of the memory leak
}
public void mousePressed(MouseEvent e) { //kaw is a mouseListener
doPopup(e);
}
public void mouseClicked(MouseEvent e) {
doPopup(e);
}
public void mouseReleased(MouseEvent e) {
doPopup(e);
}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
private void doPopup(MouseEvent e) {
if (e.isPopupTrigger()) {
popupMenu.show(this, e.getX(), e.getY()); //x & y of position of mouse during rt-click
}
}
public static void main (String args[]) {
KevAppWindow kaw = new KevAppWindow ("To show Java Memory Leak, right click for popup and Select!");
kaw.setVisible (true);
//kaw.kevDFAction.doAction(); //no memory leak if run from here, but call this from a popup and she runs out of memory right away
}
}
FILE2:
package kevin;
import javax.swing.*;
import java.awt.event.*;
public class KevDFAction extends AbstractAction {
public KevDFAction(boolean enabled ) {
super ("Kev Action");
}
public void doAction () {
System.out.println("Kev Action");
for (int j = 0; j < 10000; j++) {
KevDialog kDialog = new KevDialog();
kDialog.dispose(); //don't need this, but just to make the point
}
}
public void actionPerformed(ActionEvent e)
{
//System.out.println("Action Performed");
doAction();
}
public static void main (String[] args) { //in search of the memory leak
KevDFAction kAction = new KevDFAction(true);
kAction.doAction();
}
}
FILE 3:
package kevin;
import javax.swing.*;
import java.lang.*;
import java.awt.*;
public class KevDialog extends JDialog {
private String[] options = new String[1000];
private static int dialogCount;
public KevDialog() {
++dialogCount;
System.out.println("*******Instantiating KevDialog: count= " + dialogCount);
for (int i = 0; i < 1000; i++) {
options[i] = new String("OPTION_Take up some space_" + i);
}
}
public void finalize() throws Throwable {
--dialogCount;
System.out.println("*******Finalizing KevDialog: count= " + dialogCount);
super.finalize();
}
public static void main (String[] args) {
for (int j = 0; j < 10000; j++) {
KevDialog kDialog = new KevDialog();
kDialog.dispose();
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
I have to make all my large jobs standalone programs as I can't incorporate them into a menu system. Very user unfriendly.
- duplicates
-
JDK-4649647 JFrame instances are not garbage collected upon disposal
- Closed