Talk:CompilerOptimizations

From APIDesign

Jump to: navigation, search

The JVM's threading and synchronization specification is extremely clear and exhaustive for this kind of thing. Remember that the garbage collector runs in one or more threads, separate from the thread of execution in your test program. Changes made within your test program follow JVM rules for when those changes are made visible to other threads. You have no synchronization mechanism in place, so according to the specification changes you are making need not be visible to the garbage collector.

In particular, the returned string value doesn't necessarily have to have a stack or register location, or even be retained at all. In this case you set the value to null, but hotspot can (correctly) note that the change need not be propagated to any other thread immediately, or even at all.

synchronized (this) {

 value = null;

}

Using a block like this will force thread changes to be published; when the sync block is exited changes are "published" to other threads, as necessary. Even here it is not necessarily the case. In general you cannot assume that a local object reference in a java method will be "cleaned up" in any way prior to the exit of the method. For example, hotspot might simply remove the "set to null" if nothing reads the variable later on. If you MUST influence the garbage collector from a method that, say, loops and dispatches events forever, you should use an AtomicReference to hold the value. This shifts the reference out into the heap and allows proper control over its value, and the propagation of that value to other threads (like the garbage collector).

RJudson


This discussion reminds me of the clever tricks people employed trying to correctly do double-checked locking. Tricks that weren't really working, because people were trying to rely on non-guaranteed behavior. I don't think that even "fully initializing" a variable is guaranteed to help. I would expect that even after putting the value in a local variable,

public void factory() {
    String retValue = factory();
    // further code here
}

HotSpot is free to GC the object if it the variable isn't subsequently used in the method.

AndreiBadea 15:46, 17 October 2008 (UTC)


Even the test which initializes the variable in both branches may not work as the JLS declares that the optimization can reduce reachability of the variable compared to naive reachebility. In your case retValue is not used so it can be gced right after factory call. To prevent it you have to synchronize such a block of code with finilizer. Nice article about this problem is on the Jeremy Manson's blog here: http://jeremymanson.blogspot.com/2010/01/garbage-collection-references.html

Tomas.Zezula 20:02, 06 April 2010 (CET)

Personal tools
buy