1

I made a JFrame (call it J1) that includes a JButton. When the button is clicked, a new JFrame (call it J2) opens. J1 also has an ArrayList that contains J2, and all other Jframes that were opened. J2 is set to DISPOSE_ON_CLOSED I set for J2 a windowClosed() method. For testing, inside the JFrame I looped threw the ArrayList, until I get to the current J2 that was just closed, and surprisingly when I do J2.setVisisble(true) the J2 window returns!

I also checked threw the Task Manager, and saw the though opening a new J2, will make the overall program consume more RAM, closing each J2 doesn't show much difference on the Task Manager, it doesn't look like any memory was freed. It looks like that the memory consumption is going back to "normal" after a few seconds, so i doubt that is has anything to do directly with the J2.

I tried printing (System.out.print) all the ArrayList content every time a new J2 is initiated, and after opening a window, closing it, and opening a new one, I get the following messgae:

home.ATMmachine[frame0,252,198,620x420,invalid,hidden,layout=java.awt.BorderLayout,title=ATM Machine No.1,resizable,normal,defaultCloseOperation=DISPOSE_ON_CLOSE,rootPane=javax.swing.JRootPane[,9,38,602x373,invalid,layout=javax.swing.JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777673,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true]

This means that the J2 wasn't completely deleted!

The JFrame dispose() method is suppose to

Releases all of the native screen resources used by this Window, its subcomponents, and all of its owned children. That is, the resources for these Components will be destroyed, any memory they consume will be returned to the OS, and they will be marked as undisplayable.

So am I just wrong, and the frame is being deleted sum time later.

If not, then how can i delete the frame in such a way that referencing to it would be like referencing to null?

789
  • 718
  • 1
  • 10
  • 30
  • 2
    `"closing each J2 doesn't show much difference on the Task Manager,..."` -- likely because GC'ing occurs only when needed, so while your object is marked for GC'ing, it may not have already been collected because there has been no need. On a side note -- why all the JFrames? Most programs I've used that throw a lot of windows at you seem to be quite annoying, which I guess is why I usually only see them created in this way by newbie programmers. Why not swap views instead with a CardLayout? – Hovercraft Full Of Eels Sep 29 '14 at 21:19
  • 1
    `"J2.setVisisble(true)"` -- no surprise here. Calling `dispose()` releases resources. Calling `setVisible(true)` re-creates and re-uses resources. You've still got a reference to the object then if you can set it visible again, so no GC'ing will occur. – Hovercraft Full Of Eels Sep 29 '14 at 21:22
  • `"This means that the J2 wasn't completely deleted!"` -- You don't want to confuse objects with resources which is exactly what you're doing here. You've maintained a reference to the object (else the println couldn't be done), so of course it exists and will always exist until the references no longer exist (you can't print anything out), and since it continues to exist of course printing it out will return what you see. – Hovercraft Full Of Eels Sep 29 '14 at 21:27
  • very well said ... but about the newbie thing , sometimes you need a new frame for when another task needs to be done while still having the first task visible .Like a live camera monitoring app , and another JFrame for recording .Though i agree its quite annoying especially the icons that show up in the task bar – vlatkozelka Sep 29 '14 at 21:32
  • @vlatkozelka: no, you're wrong. The new window if absolutely needed should be a dialog window such as a JDialog, not a JFrame. You don't want another independent program complete with icon on the system's task bar, do you? And the new window is a child window of the main window, so therefore it should be a dialog, either modal or non-modal depending on the need. – Hovercraft Full Of Eels Sep 29 '14 at 21:36
  • I'm just learning swing, so I'm trying all kinds of things. But isn't there a way to destroy the object completely, other than creating it locally? I would like a method that would change the reference of the object to null, so it can not be referenced any longer. – 789 Oct 01 '14 at 10:04
  • This is not a Swing question but rather a general Java question: can you create a method that "deletes" an object, and the answer is NO. As long as a strong reference exists to the object, it will continue to exist. The best you can do is to try to scrub all references to the object. – Hovercraft Full Of Eels Oct 01 '14 at 16:12

2 Answers2

5

I made a JFrame (call it J1) that includes a JButton. When the button is clicked, a new JFrame (call it J2) opens. J1 also has an ArrayList that contains J2, and all other Jframes that were opened. J2 is set to DISPOSE_ON_CLOSED I set for J2 a windowClosed() method. For testing, inside the JFrame I looped threw the ArrayList, until I get to the current J2 that was just closed, and surprisingly when I do J2.setVisisble(true) the J2 window returns!

Closing the JFrame and disposing does not destroy the JFrame object, but rather it releases system resources, the resources needed to display the window on your OS. This is entirely different from the object itself. When you call setVisible(true) on a disposed JFrame, the resources are re-created, and the window is re-displayed. No objects are created or destroyed by this.

I also checked threw the Task Manager, and saw the though opening a new J2, will make the overall program consume more RAM, closing each J2 doesn't show much difference on the Task Manager, it doesn't look like any memory was freed. It looks like that the memory consumption is going back to "normal" after a few seconds, so i doubt that is has anything to do directly with the J2.

No surprise there.

I tried printing (System.out.print) all the ArrayList content every time a new J2 is initiated, and after opening a window, closing it, and opening a new one, I get the following messgae:

home.ATMmachine[frame0,252,198,620x420,invalid,hidden,layout=java.awt.BorderLayout,title=ATM Machine No.1,resizable,normal,defaultCloseOperation=DISPOSE_ON_CLOSE,rootPane=javax.swing.JRootPane[,9,38,602x373,invalid,layout=javax.swing.JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777673,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true]

This means that the J2 wasn't completely deleted!

Again, you're confusing objects, which will exist as long as a reference to the object exists, and resources.

The JFrame dispose() method is suppose to Releases all of the native screen resources used by this Window, its subcomponents, and all of its owned children. That is, the resources for these Components will be destroyed, any memory they consume will be returned to the OS, and they will be marked as undisplayable.

Exactly.

So am I just wrong, and the frame is being deleted sum time later.

An object can only be GC'd when there are no more strong references to it, and the garbage collector only does this when it feels the need to do so, such as when memory is about to run out.

If not, then how can i delete the frame in such a way that referencing to it would be like referencing to null?

Just like any other object. You could create it locally for one, but be careful since Swing listeners have a way to create strong references that you would assume should be weak, and thus make objects persist for longer than you'd like.


On a side note -- why all the JFrames? Most programs I've used that throw a lot of windows at you seem to be quite annoying, which I guess is why I usually only see them created in this way by newbie programmers. Why not swap views instead with a CardLayout?

Please check out: The Use of Multiple JFrames, Good/Bad Practice? for more on this

Community
  • 1
  • 1
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • I'm just learning swing, so I'm trying all kinds of things. But isn't there a way to destroy the object completely, other than creating it locally? I would like a method that would change the reference of the object to null, so it can not be referenced any longer. – 789 Oct 01 '14 at 10:01
0

The frame j2 is still referenced in the ArrayList by a pointer , so the garbage collector can't dispose of it yet ... try deleting the pointer from the arraylist, then even if j2 is still there in RAM , it wouldnt have any reference in your program and so garbage collector should remove it at next pass , or if u invoke system.gc() .

vlatkozelka
  • 909
  • 1
  • 12
  • 27
  • [`System.gc()`](http://docs.oracle.com/javase/7/docs/api/java/lang/System.html#gc%28%29) is just a suggestion. It`s not guaranteed that anything will happen, – Gerold Broser Sep 29 '14 at 22:00
  • yeah thanks for pointing that out , just tried to deliver the message in the easiest way possible to the person who asked ;) – vlatkozelka Sep 29 '14 at 22:06