Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > do self references cause memory leaks in Java?

Reply
Thread Tools

do self references cause memory leaks in Java?

 
 
Doug Pardee
Guest
Posts: n/a
 
      07-16-2003
"Steve Horsley" <(E-Mail Removed)_SPAM.net> wrote:
> A full Garbage Collection will only run when the VM doesn't have enough
> memory to create a new Object when required. A short-lived program or a
> program that dives into a tight loop without creating and discarding many
> objects may never trigger a full GC.


This is only true for certain environments.

The JVM specification declares that the behavior of the garbage
collector is not defined, and the JVM implementor has a free hand. The
only requirements are that there be a garbage collector, and that it
make its best effort to reclaim memory before throwing the
OutOfMemoryError.

Most of us are using Sun JVMs, and Sun has documented their GCs fairly
well. It's worth the trip to the Sun Web site to read the facts,
rather than relying on conjecture.

Modern Sun JVMs use multiple heaps, with separate garbage collectors
on each. These typically DO run on an as-needed basis, but in many
cases a "full GC" is never triggered even in a program that creates
and discards many objects.

On the other hand, if you're using RMI, the Distributed Garbage
Collector will force a "full GC" on a regular basis. By default, the
DGC triggers a full garbage collection every 60 seconds.

> This is why finalize() cannot be
> relied on to clean up resources - the program may terminate normally
> without the finalizers ever running.


Again, not *necessarily* true. It is true for the default situation,
but if you call System.runFinalizersOnExit(true) at some point, the
finalizers will always be executed. Heh... unless someone calls
System.runFinalizersOnExit(false) after you've called it with "true"

 
Reply With Quote
 
 
 
 
Doug Pardee
Guest
Posts: n/a
 
      07-16-2003
http://www.velocityreviews.com/forums/(E-Mail Removed) (Ian deSouza) wrote:
> I think it might be worthwhile talking about the mark-and-sweep GC
> that you had previously mentioned.
> [snip]
> Mark-and-sweep been in place since at least 1.1 (maybe before)..


Historically, Sun JVMs have not used mark-and-sweep GCs.

The older Sun JVMs used mark-and-compact. The difference is that
mark-and-sweep leaves a checkerboarded heap.

Modern Sun JVMs (since 1.2.something) use multiple heaps, divided into
two generations for user objects and a third generation for system
objects. The two user generations use separate garbage collectors. The
young generation uses a single-pass "copying" garbage collector: all
live objects are copied from Eden and the current survivor space into
the new survivor space and possibly the tenured generation, and then
Eden and the current survivor space are declared empty, and the new
survivor space becomes the current survivor space. The tenured
generation uses mark-and-compact.

As of 1.4.1, Sun's JVMs have added some additional GC options, one of
which is a low-latency, mostly concurrent, mark-and-sweep GC for the
tenured generation. Its operation is a six-phase process that is a
*bit* more complicated than an ordinary mark-and-sweep. See the FAQ
reference below.

A couple of useful references:
http://java.sun.com/docs/hotspot/gc1.4.2/faq.html
http://java.sun.com/docs/hotspot/gc1.4.2/
 
Reply With Quote
 
 
 
 
S. Balk
Guest
Posts: n/a
 
      07-16-2003
> Hi, I am doing some work with Java and C++ and am curious as to whether
self
> references in Java cause memory leaks.
>
> For example:
>
> class Test{
> Object foo =this;
> }
>
> If I instantiate Test, the reference count of any Test object will never
> become zero (as it always keeps a reference to itself) so long as the foo
> variable is never re-assigned.
>
> Does this present a problem for Java's garbage collection?


why don't you stress-test this little class by generating trillions of
objects, and watch the GC-log


 
Reply With Quote
 
Roedy Green
Guest
Posts: n/a
 
      07-16-2003
On Wed, 16 Jul 2003 10:44:22 +0200, "S. Balk"
<(E-Mail Removed)0spam.nl> wrote or quoted :

>watch the GC-log


how would he to that?

--
Canadian Mind Products, Roedy Green.
Coaching, problem solving, economical contract programming.
See http://mindprod.com/jgloss/jgloss.html for The Java Glossary.
 
Reply With Quote
 
Steve Horsley
Guest
Posts: n/a
 
      07-16-2003
On Tue, 15 Jul 2003 21:47:11 -0700, Doug Pardee wrote:

> "Steve Horsley" <(E-Mail Removed)_SPAM.net> wrote:


>> This is why finalize() cannot be
>> relied on to clean up resources - the program may terminate normally
>> without the finalizers ever running.

>
> Again, not *necessarily* true. It is true for the default situation,
> but if you call System.runFinalizersOnExit(true) at some point, the
> finalizers will always be executed. Heh... unless someone calls
> System.runFinalizersOnExit(false) after you've called it with "true"
>


runFinalizerdOnExit() is deprecated as "inherently unsafe".

Steve
 
Reply With Quote
 
S. Balk
Guest
Posts: n/a
 
      07-16-2003
> >watch the GC-log
>
> how would he to that?


by using java -verbose:gc



another way is to set the maximum amount of allocatable memory to a very low
value, for example 2MB, then create 4 million objects with references to
itself and wait for an OutOfMemoryError, although this is a quite dirty way
of testing ofcourse


 
Reply With Quote
 
Robert Olofsson
Guest
Posts: n/a
 
      07-17-2003
: I ran this through JProfiler (anybody want to fund me so I can buy a
: license? I'm still doing backpayments on my 20' plasma tv).

Use a free profiler instead or keep switching between optimizeit, jprobe and
jprofiler.

: class SelfReferent
: {
: Object refrerer;
: SelfReferent(Object referent)
: {
: referer = referent;
: }
: }

Ok, this code does not compile, refrerer is mispelled. So obviously this
is not the code you used.

: If I run this test, and call System.gc() manually on JProfile, there are
: still 8 allocations left on the heap (240 bytes). While this doesn't
: seem serious, it is a problem if such code is present in a long-running
: server process. This is reproducible.

If I fix your spelling error and run it with jdk/1.4.2 and my profiler, jmp,
I see that my jvm does not call GC before the test is over so I have
1000 instances of SelfReferent and 1000 instances of SelfReference.
After calling GC all of them dissapears. So my jvm does seem to handle this
case in a good way.

(to test this I added a System.in.read (); in main, after the call to test).

: So I must say that self references aren't a problem, but circular
: dependencies are.

Self references are not a problem, neither is circular references.
As someone already said, can you be sure that jprofiler-GC does a
full GC.
Also: when did you get the numbers? your test case exits very quickly so
had the GC been completed before your jvm was shut down?

/robo

 
Reply With Quote
 
Bent C Dalager
Guest
Posts: n/a
 
      07-17-2003
In article <(E-Mail Removed). back.org>,
dhek bhun kho <(E-Mail Removed)> wrote:
>> Do you have reason to believe that JProfile's manual GC does a
>> complete GC?

>
>Yes. The manual states it, according to the manual they use JVMPI to
>interact with the JVM. Or I might have found a 'bug' in their software. I
>tried sample sizes from 10-10000; and keep getting a few left over
>objects. This does not happen if I use the non-circular dependent version.


I'm not familiar with JVMPI so I'll just assume they know what they're
talking about <g>

>What am I doing wrong?


Nothing that I can think of.

>> Also, your program should be terminating long before you have any
>> chance of running a manual GC. Are you sure you're not just looking at
>> a static heap image representing the state your program was in as it
>> was about to terminate?

>
>I don't think so. The profiler keeps the VM alive after the main method
>exits.


Does it do this in some mystical magical way or has it just fired up
its own non-daemon thread to keep it all ticking merrily on? If it's
magical, that might affect how things are collected (or not) I
suppose.

>If I do not call gc() manually (of which I do not know how it is really
>invoked, would have to check JVMPI documentation) then _all_
>allocations are still visible (after the main method has finished). This
>happens with both versions of the minimal test code.
>
>When I do call the gc() method, all allocations disappear for the self
>referring version and for the circular dependent one a few allocations are
>still there. When I wrap the object referred to by the new call within a
>SoftReference object, no allocations remain after calling the garbage
>collector through the profiler.


I'm out of ideas then.

>I must admit that this is not the most ideal and idealistic test at all.
>Do you know by chance, how to 100% certain? TIA.


I have generally accepted that garbage collection is (apparantly)
non-deterministic and that however much I try to threaten it or yell
at it, it will still collect in its own good time. I tend to use
OptimizeIt to track down memory leaks and find my efforts constantly
frustrated by the fact that even when I have correctly unregistered
all my listeners, diposed all my windows, etc., it will still take up
to several minutes for the GC to catch on - even after hitting the
"collect" button in the profiler.

I don't really know how to get around this. Try to let the thing sit
for a couple of hours before checking on it again I suppose

Cheers
Bent D
--
Bent Dalager - (E-Mail Removed) - http://www.pvv.org/~bcd
powered by emacs
 
Reply With Quote
 
Bent C Dalager
Guest
Posts: n/a
 
      07-17-2003
In article <bf5gmq$hda$(E-Mail Removed)>,
Robert Olofsson <(E-Mail Removed)> wrote:
>: I ran this through JProfiler (anybody want to fund me so I can buy a
>: license? I'm still doing backpayments on my 20' plasma tv).
>
>Use a free profiler instead or keep switching between optimizeit, jprobe and
>jprofiler.


Are you aware of any decent free ones?

>If I fix your spelling error and run it with jdk/1.4.2 and my profiler, jmp,
>I see that my jvm does not call GC before the test is over so I have
>1000 instances of SelfReferent and 1000 instances of SelfReference.
>After calling GC all of them dissapears. So my jvm does seem to handle this
>case in a good way.


Did you fix the "this"-bug in order to get circular references?

Cheers
Bent D
--
Bent Dalager - (E-Mail Removed) - http://www.pvv.org/~bcd
powered by emacs
 
Reply With Quote
 
dhek bhun kho
Guest
Posts: n/a
 
      07-17-2003
(E-Mail Removed) (Bent C Dalager), Thu, 17 Jul 2003 07:17:03 +0000:

> In article <bf5gmq$hda$(E-Mail Removed)>,
> Robert Olofsson <(E-Mail Removed)> wrote:
>>: I ran this through JProfiler (anybody want to fund me so I can buy a
>>: license? I'm still doing backpayments on my 20' plasma tv).
>>
>>Use a free profiler instead or keep switching between optimizeit, jprobe and
>>jprofiler.

>
> Are you aware of any decent free ones?


None. Are you aware of any decent free ones?

>>If I fix your spelling error and run it with jdk/1.4.2 and my profiler, jmp,


Jmp? Which one is that?

>>I see that my jvm does not call GC before the test is over so I have
>>1000 instances of SelfReferent and 1000 instances of SelfReference.
>>After calling GC all of them dissapears. So my jvm does seem to handle this
>>case in a good way.


Thanks for running the test case.

The JProfiler automatically starts the memory profiling while launching
the JVM. It overrides the system.exit() and keeps the main thread alive
(how I do not know, it could be an extra thread or blocking i/o). Because
gc() is not called before the VM exits, all allocations are still there
and only 'vanish'/' freed' when I hit gc() manually through the profiler.

I'm starting to think that the results I found are an artifact. I would
have to test it again on another profiler just to be sure. I'm using the
1.4.1_03 version. On the other hand : 240 bytes won't kill a server.

Greets
Bhun.
 
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
Access Violation Errors - Can Memory Leaks cause these? nmehring@gmail.com C++ 6 06-11-2008 03:09 PM
__autoinit__ (Was: Proposal: reducing self.x=x; self.y=y;self.z=z boilerplate code) falcon Python 0 07-31-2005 05:41 PM
Re: __autoinit__ (Was: Proposal: reducing self.x=x; self.y=y;self.z=z boilerplate code) Ralf W. Grosse-Kunstleve Python 2 07-12-2005 03:20 AM
Proposal: reducing self.x=x; self.y=y; self.z=z boilerplate code Ralf W. Grosse-Kunstleve Python 16 07-11-2005 09:28 PM
__autoinit__ (Was: Proposal: reducing self.x=x; self.y=y;self.z=z boilerplate code) Ralf W. Grosse-Kunstleve Python 18 07-11-2005 04:01 PM



Advertisments