Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > Closing/Despose of JFrame

Reply
Thread Tools

Closing/Despose of JFrame

 
 
Jesper Johnsen
Guest
Posts: n/a
 
      06-28-2012
How do I remove an object lets say a JFrame from memory?
I know that the garbage collector handles this - but this simple example does not release itself...
java.exe uses 10mb in the first wait stage, this increases to 20mb when the JFrame is shown, but the memory usage never returns to the initial 10mb.
So the garbage collector never removes the object from memory - why?

package jframetest;

import javax.swing.JFrame;

public class JFrameTest {

public static void main(String[] args) {
try{
Thread.sleep(5000);
}catch(Exception Ex){}
JFrame frame = new JFrame("Test");
frame.setVisible(true);
try{
Thread.sleep(5000);
}catch(Exception Ex){}
frame.setVisible(false);
frame.dispose();
frame = null;
while(1==1){
try{
Thread.sleep(100);
}catch(Exception Ex){}
}
}

}
 
Reply With Quote
 
 
 
 
markspace
Guest
Posts: n/a
 
      06-28-2012
On 6/28/2012 6:38 AM, Jesper Johnsen wrote:
> How do I remove an object lets say a JFrame from memory?
> I know that the garbage collector handles this - but this simple example does not release itself...
> java.exe uses 10mb in the first wait stage, this increases to 20mb when the JFrame is shown, but the memory usage never returns to the initial 10mb.
> So the garbage collector never removes the object from memory - why?



Why? Because the garbage collector never needs to remove the object.
You're using 20mb out of maybe 100mb to 1000mb or more? So the garbage
collector looks at that and says "plenty o' room left!" and doesn't run.

It's weird if you're used to having explicit control over object
destruction, but it works. More importantly it's efficient. Waiting,
and then removing lots of objects at once, is actually best for
throughput in the long run.

If you really need different behavior, check out Oracle's documentation
on tuning the garbage collector. You can choose what I believe is
called an incremental garbage collector which will work more like what
you are thinking.

<http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html>

Found via Google with search terms "java garbage collection tuning".
Learn to STFW.

 
Reply With Quote
 
 
 
 
Stefan Ram
Guest
Posts: n/a
 
      06-28-2012
Jesper Johnsen <(E-Mail Removed)> writes:
>JFrame frame = new JFrame("Test");


public class Main implements java.lang.Runnable
{ public void run()
{ java.lang.Runtime.getRuntime().gc();
try { java.lang.Thread.sleep( 1000 ); } catch( final java.lang.InterruptedException interruptedException ){}
java.lang.System.out.println( java.lang.Runtime.getRuntime().freeMemory() + " Bytes free without JFrame." );
for( int i = 0; i < 999; ++i )
{ java.lang.System.out.println();
javax.swing.JFrame frame = new javax.swing.JFrame();
frame.pack();
frame.setVisible( true );
try { java.lang.Thread.sleep( 1000 ); } catch( final java.lang.InterruptedException interruptedException ){}
java.lang.Runtime.getRuntime().gc();
try { java.lang.Thread.sleep( 1000 ); } catch( final java.lang.InterruptedException interruptedException ){}
java.lang.System.out.println( java.lang.Runtime.getRuntime().freeMemory() + " Bytes free with JFrame." );
frame.dispose();
frame = null;
try { java.lang.Thread.sleep( 1000 ); } catch( final java.lang.InterruptedException interruptedException ){}
try { for( int j = 1; ; j *= 2 )java.lang.String.valueOf( new byte[ j ] ); }catch( final java.lang.Throwable throwable ){}
try { java.lang.Thread.sleep( 1000 ); } catch( final java.lang.InterruptedException interruptedException ){}
java.lang.Runtime.getRuntime().gc();
try { java.lang.Thread.sleep( 1000 ); } catch( final java.lang.InterruptedException interruptedException ){}
java.lang.System.out.println( java.lang.Runtime.getRuntime().freeMemory() + " Bytes free without JFrame." ); }}

public static void main( final java.lang.String[] args )
{ try { javax.swing.SwingUtilities.invokeAndWait( new Main() ); }
catch( final java.lang.InterruptedException interruptedException ){}
catch( final java.lang.reflect.InvocationTargetException invocationTargetException ){} }}

15960272 Bytes free without JFrame.

15653064 Bytes free with JFrame.
15846872 Bytes free without JFrame.

15842304 Bytes free with JFrame.
15860504 Bytes free without JFrame.

15854872 Bytes free with JFrame.
15863136 Bytes free without JFrame.

15858568 Bytes free with JFrame.
15862568 Bytes free without JFrame.

15858000 Bytes free with JFrame.
15859232 Bytes free without JFrame.

15853240 Bytes free with JFrame.
15853808 Bytes free without JFrame.

15849240 Bytes free with JFrame.
15849720 Bytes free without JFrame.

15844040 Bytes free with JFrame.
15844560 Bytes free without JFrame.

15839992 Bytes free with JFrame.
15840472 Bytes free without JFrame.

15835904 Bytes free with JFrame.
15836384 Bytes free without JFrame.

15831720 Bytes free with JFrame.
15832256 Bytes free without JFrame.

15820216 Bytes free with JFrame.
....

 
Reply With Quote
 
Lew
Guest
Posts: n/a
 
      06-28-2012
markspace wrote:
> Jesper Johnsen wrote:
>> How do I remove an object lets say a JFrame from memory?
>> I know that the garbage collector handles this - but this simple example does not release itself...
>> java.exe uses 10mb in the first wait stage, this increases to 20mb when the JFrame is shown, but the memory usage never returns to the initial 10mb.
> > So the garbage collector never removes the object from memory - why?

>
>
> Why? Because the garbage collector never needs to remove the object.
> You're using 20mb out of maybe 100mb to 1000mb or more? So the garbage
> collector looks at that and says "plenty o' room left!" and doesn't run.
>
> It's weird if you're used to having explicit control over object
> destruction, but it works. More importantly it's efficient. Waiting,
> and then removing lots of objects at once, is actually best for
> throughput in the long run.
>
> If you really need different behavior, check out Oracle's documentation
> on tuning the garbage collector. You can choose what I believe is
> called an incremental garbage collector which will work more like what
> you are thinking.
>
> <http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html>
>
> Found via Google with search terms "java garbage collection tuning".
> Learn to STFW.


Shut the front window?

Both oracle.com and https://www.ibm.com/developerworks/java/ have
excellent articles and white papers on Java garbage collection, how it
works and how you can fine tune it.

Make sure you have a problem before you try to solve it, but it is
always useful to gather knowhow.

The default generational garbage collector works well, especially
for idiomatic Java. As Brian Goetz points out in his Developerworks
articles, the allocation cost in the heap is very tiny, on the order of
a dozen or so machine instructions. Deallocation is likewise not
very expensive for short-lived objects. Young objects live in the
young generation heap, and dead ones are ignored during
minor GCs.

If most objects are short-lived, as should be true if one follows
best practices for scoping variables, then most GC cycles will gather
about 3% of live objects, ignoring the 97% of unreachable ones.
This is a very fast copy and shouldn't burden your throughput
very much.

When objects survive enough minor GC cycles, they move to
the tenured generation, a different area of heap. These are only
collected during major GC cycles, which use different and somewhat
slower algorithms under default setup. The major cycles are the
ones we tend to notice. So if an object is going to survive to tenure,
aim to have it survive for a very long time thereafter. Otherwise
use idioms that help objects die young.

For example, dying young:

public class Example
{
Collection<Foo> foos = getSomeFoos();
public void run()
{
for (Foo foo : foos)
{
Bar bar = foo.obtainBar();
// do whatever with 'bar'
// 'bar' falls out of scope
// if nothing else points to the same object
// it is gone in the next minor GC
}
}
}

Dying old:

public class Example
{
Collection<Foo> foos = getSomeFoos();
Bar bar; // the elephant in the room
public void run()
{
for (Foo foo : foos)
{
bar = foo.obtainBar();
// do whatever with 'bar'
// 'bar' does not fall out of scope
// The last reference from the loop lasts as
// long as this instance does, and could
// tenure the 'Bar' it points to
}
}
}

So coding things the first way, which chance are is
more correct logically, tends to reduce the impact of
GC on performance. It tilts the GC towards very rapid,
almost negligible young-generation collections and
less toward the slower, more intrusive tenured-generation
collections.

Read widely and carefully. There are some notable urban
legends out there, such as the advice to set all references
to 'null' when finished with them. There are specific times
to do so, such as when a collection such as a 'Stack' is
holding hidden references ("packratting", or the Java version
of a memory leak). Otherwise it's just superstition.

--
Lew
 
Reply With Quote
 
Stefan Ram
Guest
Posts: n/a
 
      06-28-2012
http://www.velocityreviews.com/forums/(E-Mail Removed)-berlin.de (Stefan Ram) writes:
>Jesper Johnsen <(E-Mail Removed)> writes:
>>JFrame frame = new JFrame("Test");

>public class Main implements java.lang.Runnable


public class Main implements java.lang.Runnable
{ public void run()
{ for( ;; )
{ java.lang.System.out.println( java.lang.Runtime.getRuntime().freeMemory() + " Bytes free." );
javax.swing.JFrame frame = new javax.swing.JFrame();
frame.pack(); frame.setVisible( true ); frame.dispose(); frame = null; }}

public static void main( final java.lang.String[] args ) throws java.lang.Throwable
{ javax.swing.SwingUtilities.invokeAndWait( new Main() ); }}

The above program shows declining amounts of free memory for
some time. Then, a gc seems to be triggered, which reclaims
a part of the memory. After several such gcs, there is less
and less memory reclaimed and one feels that soon an
unrecoverable out-of-memory error will happen. But then a
real deep major gc seems to be triggered that seems to
reclaim all or nearly all of the memory! (I stopped it then,
maybe someone wants to have this running overnight?)

 
Reply With Quote
 
Lew
Guest
Posts: n/a
 
      06-28-2012
Stefan Ram wrote:
> Stefan Ram writes:
> >Jesper Johnsen writes:
> >>JFrame frame = new JFrame("Test");

> >public class Main implements java.lang.Runnable

>
> public class Main implements java.lang.Runnable
> { public void run()
> { for( ;; )
> { java.lang.System.out.println( java.lang.Runtime.getRuntime().freeMemory() + " Bytes free." );
> javax.swing.JFrame frame = new javax.swing.JFrame();
> frame.pack(); frame.setVisible( true ); frame.dispose(); frame = null; }}
>
> public static void main( final java.lang.String[] args ) throws java.lang.Throwable
> { javax.swing.SwingUtilities.invokeAndWait( new Main() ); }}
>
> The above program shows declining amounts of free memory for
> some time. Then, a gc seems to be triggered, which reclaims
> a part of the memory. After several such gcs, there is less
> and less memory reclaimed and one feels that soon an
> unrecoverable out-of-memory error will happen. But then a
> real deep major gc seems to be triggered that seems to
> reclaim all or nearly all of the memory! (I stopped it then,
> maybe someone wants to have this running overnight?)


Also there are answers to other incarnations of this multipost
that go into how this all works.

--
Lew
 
Reply With Quote
 
Andreas Leitgeb
Guest
Posts: n/a
 
      06-28-2012
Lew <(E-Mail Removed)> wrote:
> Dying old:
> public class Example
> {
> Collection<Foo> foos = getSomeFoos();
> Bar bar; // the elephant in the room
> public void run()
> {
> for (Foo foo : foos)
> {
> bar = foo.obtainBar();
> // do whatever with 'bar'
> // 'bar' does not fall out of scope
> // The last reference from the loop lasts as
> // long as this instance does, and could
> // tenure the 'Bar' it points to
> }
> }
> }
> [...]
> There are some notable urban
> legends out there, such as the advice to set all references
> to 'null' when finished with them. There are specific times
> to do so, such as when a collection such as a 'Stack' is
> holding hidden references ("packratting", or the Java version
> of a memory leak). [...]


....or right after the loop in above "dying old"-Example, if for
whatever reason there really was some need to have "bar" as a
field, instead of as a local var within the loop.

 
Reply With Quote
 
Lew
Guest
Posts: n/a
 
      06-29-2012
Andreas Leitgeb wrote:
> Lew wrote:
> > Dying old:
> > public class Example
> > {
> > Collection<Foo> foos = getSomeFoos();
> > Bar bar; // the elephant in the room
> > public void run()
> > {
> > for (Foo foo : foos)
> > {
> > bar = foo.obtainBar();
> > // do whatever with 'bar'
> > // 'bar' does not fall out of scope
> > // The last reference from the loop lasts as
> > // long as this instance does, and could
> > // tenure the 'Bar' it points to
> > }
> > }
> > }
> > [...]
> > There are some notable urban
> > legends out there, such as the advice to set all references
> > to 'null' when finished with them. There are specific times
> > to do so, such as when a collection such as a 'Stack' is
> > holding hidden references ("packratting", or the Java version
> > of a memory leak). [...]

>
> ...or right after the loop in above "dying old"-Example, if for
> whatever reason there really was some need to have "bar" as a
> field, instead of as a local var within the loop.


True, but dangerous. If you are nulling out the reference after the loop
anyway, there is a low probability that a member variable is the right
scope. I can think of reasons why one might do that, but they all seem
like tangled and ill-advised code to me.

The scope and lifetime of the variable should match the scope and
lifetime of the need for its reference. The scenario you describe seems
to violate that. I say "seems to" because sure, there very well could be
cases for it. But they all would (or should) fit into the "scope and lifetime
should match" rule. So if you do see a situation where the scope is the
instance, and/or the lifetime matches that of the enclosing instance, then
a member variable is correct even should Lew feel that your code is tangled
and ill advised.

OTOH, you shouldn't be too quick to dismiss my insight into the matter.

--
Lew
 
Reply With Quote
 
John B. Matthews
Guest
Posts: n/a
 
      06-29-2012
In article <(E-Mail Removed)-berlin.de>,
(E-Mail Removed)-berlin.de (Stefan Ram) wrote:

> (E-Mail Removed)-berlin.de (Stefan Ram) writes:
> >Jesper Johnsen <(E-Mail Removed)> writes:
> >>JFrame frame = new JFrame("Test");

> >public class Main implements java.lang.Runnable

>
> public class Main implements java.lang.Runnable
> { public void run()
> { for( ;; )
> { java.lang.System.out.println(
> java.lang.Runtime.getRuntime().freeMemory() + " Bytes free." );
> javax.swing.JFrame frame = new javax.swing.JFrame();
> frame.pack(); frame.setVisible( true ); frame.dispose(); frame = null;
> }}
>
> public static void main( final java.lang.String[] args ) throws
> java.lang.Throwable
> { javax.swing.SwingUtilities.invokeAndWait( new Main() ); }}
>
> The above program shows declining amounts of free memory for
> some time. Then, a gc seems to be triggered, which reclaims
> a part of the memory. After several such gcs, there is less
> and less memory reclaimed and one feels that soon an
> unrecoverable out-of-memory error will happen. But then a
> real deep major gc seems to be triggered that seems to
> reclaim all or nearly all of the memory! (I stopped it then,
> maybe someone wants to have this running overnight?)


I cited a similar experiment here, using an artificially small heap to
exaggerate the effect:

<news:(E-Mail Removed)>
<https://groups.google.com/d/msg/comp.lang.java.help/ylUG68cHsWQ/h1FMBzKirkwJ>

--
John B. Matthews
trashgod at gmail dot com
<http://sites.google.com/site/drjohnbmatthews>
 
Reply With Quote
 
Gene Wirchenko
Guest
Posts: n/a
 
      06-29-2012
On Thu, 28 Jun 2012 09:47:55 -0700 (PDT), Lew <(E-Mail Removed)>
wrote:

[snip]

>Read widely and carefully. There are some notable urban
>legends out there, such as the advice to set all references
>to 'null' when finished with them. There are specific times
>to do so, such as when a collection such as a 'Stack' is
>holding hidden references ("packratting", or the Java version
>of a memory leak). Otherwise it's just superstition.


Ah, not quite. In Visual FoxPro, at least in some versions, the
releasing of an object or an array with object references would result
in a memory leak. Setting to null was a workaround for that. I would
not be surprised if it happened in some other languages, too. However,
I would not do it unless it were required.

Sincerely,

Gene Wirchenko
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
How Can I Get One JFrame To Appear Above Another JFrame clusardi2k@aol.com Java 2 08-27-2012 03:01 PM
start a new JFrame from an existing one, and when old JFrame closes new one does not jakester Java 3 04-02-2007 11:13 PM
Re: where is the JFrame constructor Passero Java 2 07-11-2003 11:05 PM
JFrame URL Link René Kikkenborg Java 1 07-09-2003 06:55 AM
Where is the JFrame constructor? Passero Java 6 07-05-2003 08:52 AM



Advertisments