garbage collection anonymous objects?

M

Mark Space

Here's a weird thought. If I create an anonymous object then put that
object to some use, could it still be garbage collected? In particular,
given the following code, I don't see what guarantees that the thread
created won't be garbage collected.

public class ServerTest implements Runnable
{
public static void main(String[] args)
{
new Thread( new ServerTest() ).start();
}

public void run()
{
while( true )
{ //....
}
}
}

I didn't run this so sorry for any missed errors, but you get the idea.
Shouldn't the JVM garbage collect the thread at some point? This code
seems like trouble waiting to happen, but I'm sure I've seen this exact
idiom elsewhere.
 
M

Matt Humphrey

| Here's a weird thought. If I create an anonymous object then put that
| object to some use, could it still be garbage collected? In particular,
| given the following code, I don't see what guarantees that the thread
| created won't be garbage collected.
|
| public class ServerTest implements Runnable
| {
| public static void main(String[] args)
| {
| new Thread( new ServerTest() ).start();
| }
|
| public void run()
| {
| while( true )
| { //....
| }
| }
| }
|
| I didn't run this so sorry for any missed errors, but you get the idea.
| Shouldn't the JVM garbage collect the thread at some point? This code
| seems like trouble waiting to happen, but I'm sure I've seen this exact
| idiom elsewhere.

Threads are anchor objects that are not GC'd just because the application
has no reference to them. Essentially the JVM keeps the references to them
until they're no longer needed.

Matt Humphrey (e-mail address removed) http://www.iviz.com/
 
T

Twisted

I didn't run this so sorry for any missed errors, but you get the idea.
Shouldn't the JVM garbage collect the thread at some point? This code
seems like trouble waiting to happen, but I'm sure I've seen this exact
idiom elsewhere.

Running threads and their threadlocals are considered "reachable" and
ineligible for GC. So are any objects referenced by static fields of
loaded classes, any objects referenced by local variables in methods
that have not yet exited, and any objects referenced by instance
fields of any reachable object. The exceptions are objects held with
WeakReference, SoftReference, and PhantomReference that are not
otherwise reachable.

Basically, if it's possible for your code to get at the object
(without using FooReference.get()), or it's a thread whose code is
running, it can't be garbage collected. In essence, you never need to
worry that an object you're still using will just "disappear" due to
the behavior of the GC, except in the special case of those reference
objects, whose get method may start to return null a while after the
held object is no longer otherwise reachable.
 
P

Patricia Shanahan

Mark said:
Here's a weird thought. If I create an anonymous object then put that
object to some use, could it still be garbage collected? In particular,
given the following code, I don't see what guarantees that the thread
created won't be garbage collected.

public class ServerTest implements Runnable
{
public static void main(String[] args)
{
new Thread( new ServerTest() ).start();
}

public void run()
{
while( true )
{ //....
}
}
}

I didn't run this so sorry for any missed errors, but you get the idea.
Shouldn't the JVM garbage collect the thread at some point? This code
seems like trouble waiting to happen, but I'm sure I've seen this exact
idiom elsewhere.

The key definition is "A reachable object is any object that can be
accessed in any potential continuing computation from any live thread.".
http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.6

If an object is reachable, it cannot be garbage collected. The
definition does not limit reachability to objects that are referenced by
named variables.

The static method Thread.currentThread() returns the Thread object for
the calling thread. If there is either any possibility of the thread
calling it, or if the thread in any way needs its Thread object in order
to go on running, then the Thread object is reachable for the life of
the thread, regardless of whether there are any other references to it.

Patricia
 
M

Mark Space

Patricia said:
The key definition is "A reachable object is any object that can be
accessed in any potential continuing computation from any live thread.".
http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.6


Thanks to everyone who replied. It does make sense that a Thread object
is still reachable by it's own thread while that thread is running. It
just wasn't obvious to me at first. The link was also quite helpful;
thanks Patricia.
 
T

Tom Hawtin

Twisted said:
Running threads and their threadlocals are considered "reachable" and
ineligible for GC.

There's nothing special about thread-locals. Anything an object (say a
Thread) strongly references is reachable.
So are any objects referenced by static fields of
loaded classes,

Classes follow the same rules as other objects and can be collected.
any objects referenced by local variables in methods
that have not yet exited, [...]

If the local variable is dead (and remember actual execution is not
necessarily as it is written down in the source) is eligible.

Tom Hawtin
 
T

Twisted

[snip some]

I'm not sure I care for your tone, mister. This feels like an attack
post, if not a particularly violent one, one meant to make me look
foolish in public perhaps. Watch it.
There's nothing special about thread-locals. Anything an object (say a
Thread) strongly references is reachable.

I just figured it wouldn't necessarily be obvious to someone fairly
new, if the fact the thread itself can't be collected isn't obvious to
the same person. Threadlocals aren't sitting in an obvious named place
as members of something after all. (Probably some Collection in the
Thread object, but who normally looks at the source code for Thread?
Especially newbies?)
Classes follow the same rules as other objects and can be collected.

If the local variable is dead (and remember actual execution is not
necessarily as it is written down in the source) is eligible.

Corner-cases. The local variable's referent can't be collected while
it's still in use by the running code, which is what's important.
Classes statically referenced all through the running code won't be
eligible either, and that's the vast majority of them. Dynamically
loaded classes you quit referencing might go, along with their
dependents not otherwise referenced, but that I expect is about it. To
top it off, the class is loaded again if there's an attempt to access
it again anyway, so the programmer shouldn't really "notice" its
absence, unless they keep WeakReferences to say a ResourceBundle
around to see if it ever turns null.

The really important thing is that it should simply not happen
(barring VM bugs, or reference objects) that something you're still
using disappears due to the garbage collector. This obviously includes
unnamed temporaries -- it's not just

new Thread(myRunnable).start();

it's even more common stuff like

myBigInteger.plus(anotherBigInteger).times(bigFactor);

the result of the "plus" is never held by any named variable, but it
won't be garbage-collected before the "times" is invoked on it. (This
happens most frequently with temporary Strings, although such code
should really be rewritten to use StringBuffer or StringBuilder if it
is responsible for a significant amount of CPU time or memory use on
profiling.)

One weird thing is the failure of the JVM to collect unreachable
Threads that have never run. It can't ever get run if no running code
can get ahold of a reference to it to call "start" on it, after all.
Just another reason to spawn threads lazily right when you run them, I
suppose (and this includes worker thread pools -- start them all right
away after constructing them, even if they immediately start waiting
on a BlockingQueue for work to do).
 
R

Roedy Green

I'm not sure I care for your tone, mister. This feels like an attack
post, if not a particularly violent one, one meant to make me look
foolish in public perhaps. Watch it.

Unfortunately that is the common game, try to find a quibble to prove
the other guy an idiot.

But in this case, there was no disparaging intro, so I think you are
overreacting.
 
T

Twisted

But in this case, there was no disparaging intro, so I think you are
overreacting.

No disparaging intro, but the tone of the post made the whole thing
into a put-down.
 
M

Mike Schilling

Classes follow the same rules as other objects and can be collected.

Though class objects are part of a prety tangled web. Class objects
reference their classloaders (and vice versa), all objects reference their
defining classes, classloaders reference their parents, classes reference
their superclasses and other classes they use [1], etc. Removing enough
references that the cycle of a classloader and its classes can be collected
is often tricky to accomplish.

1. "use" is imprecise, but it includes (at least) the types of fields,
method returns, and method parameters.
 
T

Tom Hawtin

Mike said:
Classes follow the same rules as other objects and can be collected.

Though class objects are part of a prety tangled web. Class objects
reference their classloaders (and vice versa), all objects reference their
defining classes, classloaders reference their parents, classes reference
their superclasses and other classes they use [1], etc. Removing enough
references that the cycle of a classloader and its classes can be collected
is often tricky to accomplish.

I see an opportunity for pedantry here...

In practice, Class objects do not need to reference the classes they
use, as such. The classes used must be members of the user's class
loader or one of its parents, so are referenced that way.

But yes, very easy to cause class loader memory leaks. For instance
java.beans and java.sql.DriverManager do that (Sun implementation).
Typically there is a static map somewhere, where no combination of
WeakReferences can avoid leaking. Vote Bug ID: 6493635 "(cl)
ClassLoader-local variables similar to ThreadLocal"!

Tom Hawtin
 
R

Roedy Green

No disparaging intro, but the tone of the post made the whole thing
into a put-down.

I too find that wearing. That is partly why I withdraw from various
newsgroups periodically. The funny thing is those same people would
not dream of treating strangers face to face that way. They just get
in the habit of put downs on the net as a sort of game. And the
putdown you are complaining about was pretty minor.

Salespeople are taught to always find a way to agree with someone, to
avoid putting them down. Once you have humiliated someone, there is no
way he will ever admit to agreeing with you.

Male mountain goats butt heads to determine status. We humans do it
with putdowns.

In person, the same behaviour may have jocular intonation. The poker
face of the Internet makes everything seem more grave than it was
intended.

"You add just as much suffering to the world when you take offence as
when you give offence."
~ Ken Keyes
 
R

Roedy Green

If I create an anonymous object then put that
object to some use, could it still be garbage collected?

all objects are anonymous. There is no one-to-one relationship
between objects and variables.

The JVM keeps track of threads, so those threads and their stacks and
the variables on them are considered live.
 
L

Lew

Roedy said:
I too find that wearing. That is partly why I withdraw from various
newsgroups periodically. The funny thing is those same people would
not dream of treating strangers face to face that way. They just get
in the habit of put downs on the net as a sort of game. And the
putdown you are complaining about was pretty minor.


Y'know, I've been over and over and over Tom's post, and for the life of me I
see nothing even remotely resembling a "tone of the post [that] made the whole
thing into a put-down". It contained nothing but facts, and those germane to
the topic. Y'all are paranoid. The first hint of anything negative was in
the response to that post:
I'm not sure I care for your tone, mister. This feels like an attack
post, if not a particularly violent one, one meant to make me look
foolish in public perhaps. Watch it.

which was both hostile and threatening in tone. Before that I can see no
indication of anything to provoke such a reaction.

The flip side of what Roedy said is that we have to understand the medium of
Usenet, and not ascribe negativity unless there is clear and overwhelming
evidence of it. Otherwise those who react are the
Male mountain goats [who] butt heads to determine status.
 
M

Mike Schilling

Lew said:
Roedy said:
I too find that wearing. That is partly why I withdraw from various
newsgroups periodically. The funny thing is those same people would
not dream of treating strangers face to face that way. They just get
in the habit of put downs on the net as a sort of game. And the
putdown you are complaining about was pretty minor.


Y'know, I've been over and over and over Tom's post, and for the life of
me I see nothing even remotely resembling a "tone of the post [that] made
the whole thing into a put-down". It contained nothing but facts, and
those germane to the topic. Y'all are paranoid. The first hint of
anything negative was in the response to that post:
I'm not sure I care for your tone, mister. This feels like an attack
post, if not a particularly violent one, one meant to make me look
foolish in public perhaps. Watch it.

which was both hostile and threatening in tone. Before that I can see no
indication of anything to provoke such a reaction.

What Lew said.
 
E

Eric Sosman

Mike Schilling wrote On 07/17/07 17:35,:
Roedy said:
No disparaging intro, but the tone of the post made the whole thing
into a put-down.

I too find that wearing. That is partly why I withdraw from various
newsgroups periodically. The funny thing is those same people would
not dream of treating strangers face to face that way. They just get
in the habit of put downs on the net as a sort of game. And the
putdown you are complaining about was pretty minor.


Y'know, I've been over and over and over Tom's post, and for the life of
me I see nothing even remotely resembling a "tone of the post [that] made
the whole thing into a put-down". It contained nothing but facts, and
those germane to the topic. Y'all are paranoid. The first hint of
anything negative was in the response to that post:
I'm not sure I care for your tone, mister. This feels like an attack
post, if not a particularly violent one, one meant to make me look
foolish in public perhaps. Watch it.

which was both hostile and threatening in tone. Before that I can see no
indication of anything to provoke such a reaction.


What Lew said.

What Lew and Mike said. In other words, "Me, too!"
 

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

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top