Need to protect method-local object against GC?

S

Steve Brecher

class Foo<Integer> implements Collection<Integer> {...}

class Bar {

Foo<Integer> aFoo() {
return new Foo<Integer>(...);
}

void method() {
for (Integer i : aFoo())
...;
}

During the loop execution method will not have an instance of Foo on its
stack, but only an instance of Iterator<Integer>, and thus I think that
there is no instance of Foo that a garbage collector can see as live, and
hence the instance created by aFoo is subject to destruction during the
loop. Therefore it is necessary to write instead something like,

myFoo = aFoo();
for (Integer i : myFoo)
...;

Right?
 
S

Steve Brecher

Steve Brecher said:
During the loop execution method will not have an instance of Foo on
its stack, but only an instance of Iterator...

But the Iterator has to have stored, or be associated with by virtue of
being a nested class, an instance of Foo. So the loop is "GC safe."
 
P

Patricia Shanahan

Steve said:
class Foo<Integer> implements Collection<Integer> {...}

class Bar {

Foo<Integer> aFoo() {
return new Foo<Integer>(...);
}

void method() {
for (Integer i : aFoo())
...;
}

During the loop execution method will not have an instance of Foo on its
stack, but only an instance of Iterator<Integer>, and thus I think that
there is no instance of Foo that a garbage collector can see as live, and
hence the instance created by aFoo is subject to destruction during the
loop. Therefore it is necessary to write instead something like,

myFoo = aFoo();
for (Integer i : myFoo)
...;

Right?

I'm not sure about the distinction you are making. The second piece of
code is just a longer, more explicit, version one.

If the Iterator needs to reference some other object to do its job, it
is the responsibility of the Iterator implementation to ensure it either
has or can obtain that reference, not your worry when using the Iterator.

If the Iterator has or can obtain a reference to some Foo then as long
as the Iterator is reachable from some ongoing computation in an active
thread that Foo object is also reachable.

Patricia
 
M

Mark Rafn

Steve Brecher said:
class Foo<Integer> implements Collection<Integer> {...}
class Bar {
Foo<Integer> aFoo() {
return new Foo<Integer>(...);
}

void method() {
for (Integer i : aFoo())
...;
}
During the loop execution method will not have an instance of Foo on its
stack, but only an instance of Iterator<Integer>, and thus I think that
there is no instance of Foo that a garbage collector can see as live, and
hence the instance created by aFoo is subject to destruction during the
loop.

In general, an Iterator keeps a reference to it's underlying Collection. I
suppose it's possible not to, but if that were the case, why would you care if
the Foo were collected?
Therefore it is necessary to write instead something like,
myFoo = aFoo();
for (Integer i : myFoo)
...;
Right?

No. Unless your code needs a reference to the Foo, there's no reason for your
code to maintain the reference to it. Think of it this way: if the Iterator
needs the reference, it'll keep it without your help, and if it doesn't need
it, then you don't care if it gets GC'd.
 

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
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top