simple static question

B

Ben

Say i have a static queue in class A.

I instantiate class B and in the constructor I instantiate an object of
class A just to get a reference of the static queue.

Once the constructor finishes there is no reference to any object of
class A, just it's queue.

Later on I instatiate several objects of class A that will all add to
the queue.

So the question is:

if I don't have a reference to any object of class A, but I have a
reference to it's static queue, will the "lost" reference to class A I
used in the constructor be collected by the garbage collector? If yes
once a new object is constructed will the static queue have the same
address, or will a new address be given to it?

And if the address is the same, but the "lost" reference is not
collected can I take care of that memory leak, and keep the reference of
the static queue?
 
M

missaka.wijekoon

Ben said:
Say i have a static queue in class A.

I instantiate class B and in the constructor I instantiate an object of
class A just to get a reference of the static queue.

Once the constructor finishes there is no reference to any object of
class A, just it's queue.

Later on I instatiate several objects of class A that will all add to
the queue.

So the question is:

if I don't have a reference to any object of class A, but I have a
reference to it's static queue, will the "lost" reference to class A I
used in the constructor be collected by the garbage collector? If yes
once a new object is constructed will the static queue have the same
address, or will a new address be given to it?

And if the address is the same, but the "lost" reference is not
collected can I take care of that memory leak, and keep the reference of
the static queue?

As long as you keep a reference to the static member, it will not be
garbage collected. The class A obects and how they get garbage
collected may depend on the implementation of Java. As long as you
lett go of references properly, garbage collection should work.

-Missaka
 
C

Chris Uppal

Ben said:
if I don't have a reference to any object of class A, but I have a
reference to it's static queue, will the "lost" reference to class A I
used in the constructor be collected by the garbage collector? If yes
once a new object is constructed will the static queue have the same
address, or will a new address be given to it?

Unfortunately the answer is rather context-dependent. In 99% of cases the
answer is simple, but you /can/ create cases where the answer is more
complicated if you try hard enough.

In most cases, the simple answer will be correct: As long as class B is loaded
into the JVM then class A will be too, and so the queue in A will continue to
exist whether or not B keeps a reference to it. For "normal" Java programs
both A and B will be loaded for the entire lifetime of the program. So, once
the queue has been created, it will never go away again (unless you explicitly
set the static reference in A to null).

The non-simple answer applies in specialised circumstances, and /only/ applies
if someone is using custom classloaders. Unfortunately "advanced" application
frameworks (such as servlet containers, etc) /do/ make use of classloaders.
Anyway, in the more complicated case, there are again two possibilities: a
simple one which applies in nearly all cases, and a complicated one which
applies if you try hard enough.

If A and B are loaded by the same classloader, or if A is loaded by a parent of
B's classloader (which will /always/ be the case if the code in B refers to A
directly, rather than using Class.forName()), then A will live at least as long
as B. So in that case the picture is pretty-much the same as for the simple
case, except that it may be possible for both A and B to be unloaded before the
program exits (and so the queue will be discarded and cleaned up -- but that
won't usually matter because there is no longer any need for it).

The last case is most complicated, but /cannot/ apply unless you yourself are
playing games with classloaders. If the code for B does not contain any direct
references to A (no variables declared as type A, for instance), /and/ if
you've taken care to load A through a classloader which is not the one used for
B (or one of its parents), then it is possible for A to be unloaded while B is
still active. If so, then the queue will be discarded when A unloads (assuming
B has no reference to it), and if B repeats the operations it used to get a
reference to the queue the first time, then it is possible that it will see a
new queue associated with a freshly re-loaded and re-initialised version of
class A.

I hope that's not overcomplicating what you thought was a simple question. As
I say, in nearly all cases, you can treat static variables as having a lifetime
when extends to program exit.

-- chris
 
R

Remon van Vliet

As long as you keep a reference to the static member, it will not be
garbage collected. The class A obects and how they get garbage
collected may depend on the implementation of Java. As long as you
lett go of references properly, garbage collection should work.

-Missaka

No, the object referenced to by a static field will never be garbage
collected. The object that's referred to might, if the static reference is
replaced with a reference to another object. But the instance of the queue
assigned to the static field will not be garbage collected at any time.
Garbage collection occurs if, and only if, no active thread can access the
object in any way. Once the GC realizes that, the finalize() method of said
object is called, if after that call the object is still not referenced
(which might not be the case if the object is ressurected in the finalize()
method or if the finalize() method threw an exception) it is disposed.

There is actually one situation where it *might* be garbage collected.
Imagine the following class :

public class StaticGC() {

private static Queue queue = new LinkedList();

// possibly more methods that do nothing with the queue and provide no
access to it in any way
}

I cant think of a way that would grant access to the queue instance in any
way to living threads so you could assume it can be garbage collected. That
said i sincerely doubt that happens, feel free to test it.

- Remon van Vliet
 
B

Ben

Thanks for the info, it helps. Since I'm not messing with classloaders,
it's going to be pretty straight forward for me, and I won't have to
worry about it. Thanks again.

Ben
 
A

Adam Maass

Chris Uppal said:
Unfortunately the answer is rather context-dependent. In 99% of cases the
answer is simple, but you /can/ create cases where the answer is more
complicated if you try hard enough.

In most cases, the simple answer will be correct: As long as class B is
loaded
into the JVM then class A will be too, and so the queue in A will continue
to
exist whether or not B keeps a reference to it. For "normal" Java
programs
both A and B will be loaded for the entire lifetime of the program. So,
once
the queue has been created, it will never go away again (unless you
explicitly
set the static reference in A to null).

The non-simple answer applies in specialised circumstances, and /only/
applies
if someone is using custom classloaders. Unfortunately "advanced"
application
frameworks (such as servlet containers, etc) /do/ make use of
classloaders.
Anyway, in the more complicated case, there are again two possibilities: a
simple one which applies in nearly all cases, and a complicated one which
applies if you try hard enough.

If A and B are loaded by the same classloader, or if A is loaded by a
parent of
B's classloader (which will /always/ be the case if the code in B refers
to A
directly, rather than using Class.forName()), then A will live at least as
long
as B. So in that case the picture is pretty-much the same as for the
simple
case, except that it may be possible for both A and B to be unloaded
before the
program exits (and so the queue will be discarded and cleaned up -- but
that
won't usually matter because there is no longer any need for it).

The last case is most complicated, but /cannot/ apply unless you yourself
are
playing games with classloaders. If the code for B does not contain any
direct
references to A (no variables declared as type A, for instance), /and/ if
you've taken care to load A through a classloader which is not the one
used for
B (or one of its parents), then it is possible for A to be unloaded while
B is
still active. If so, then the queue will be discarded when A unloads
(assuming
B has no reference to it), and if B repeats the operations it used to get
a
reference to the queue the first time, then it is possible that it will
see a
new queue associated with a freshly re-loaded and re-initialised version
of
class A.

I hope that's not overcomplicating what you thought was a simple question.
As
I say, in nearly all cases, you can treat static variables as having a
lifetime
when extends to program exit.

-- chris

Chris, thanks for this thorough and clear explanation. I was going to try to
put one together, but gave up in frustration.

-- Adam Maass
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,430
Messages
2,571,676
Members
48,796
Latest member
Greg L.

Latest Threads

Top