Self-Mutation with Strategy Object


C

cppaddict

I have a class whose behaviour changes with state. The current
behaviour is determined by a Strategy object. Often, after a given
Strategy executes, it needs to change the object's active strategy, so
that on the next call a new Strategy will be called. The sample class
below illustrates this concept, compiles, and works.

public class Test {
public static void main (String[] args) {
Test t = new Test();
t.doIt();
t.doIt();
t.doIt();
}

private Strategy mStrategy = new Strategy1();

public void doIt() {
mStrategy.doIt();
}

interface Strategy {
public void doIt();
}
private class Strategy1 implements Strategy {
public void doIt() {
mStrategy = new Strategy2();
//Can this object be garbage collected here???
System.out.println("Executing Strategy1");
}
}
private class Strategy2 implements Strategy {
public void doIt() {
mStrategy = new Strategy1();
System.out.println("Executing Strategy2");
}
}

}

But question is: Is it safe? It seems that, where the code is marked
with a comment, the currently executing strategy is no longer referred
to by mStrategy, and so could possibly be garbage collected?

Or is this perfectly legal, because the collector will not collect an
object which is still executing code?

Thanks for any explanation,
John
 
Ad

Advertisements

D

Daniel Bonniot

Or is this perfectly legal, because the collector will not collect an
object which is still executing code?

Correct.

More precisely, an object is not executing code. The method is in the class,
and exists independently of instances of the class. The object is a parameter
(this) of the method. This means threre is a link to the instance, and
therefore the instance cannot be garbage collected before the end of the method.

Daniel

The Nice programming language: http://nice.sf.net
 
C

Chris Uppal

cppaddict said:
Or is this perfectly legal, because the collector will not collect an
object which is still executing code?

In the unlikely event that the platform as a whole (java compiler, JIT, GC
implementation, etc) could /prove/ that no reference to the object called
'this' could possibly be used, then it would be entitled to reclaim its
storage, I think. But then, if it could prove that, then -- by definition --
the code is still perfectly safe.

However that is /very/ unlikely, and so I can't imagine any sane JVM
implementor putting any effort at all into creating such an optimisation (I
suppose that it might conceivably happen as a side-effect of some other
optimisation).

To see why its so unlikely that it could ever prove such a thing, consider that
System.out.println() might throw an unchecked exception, in which case the JVM
would need a reference to the object known as 'this' to construct the stack
frame.

Bottom line: it is completely safe.

-- chris
 
Ad

Advertisements

M

Michiel Konstapel

But question is: Is it safe? It seems that, where the code is marked
with a comment, the currently executing strategy is no longer referred
to by mStrategy, and so could possibly be garbage collected?

Not to worry...
Or is this perfectly legal, because the collector will not collect an
object which is still executing code?

.... because this is indeed the case :)
Well, objects don't exactly execute code, threads do, but let's not
nitpick.

HTH,
Michiel
 

Top