Well, the optimizer can optimize
while (bigData != null) {
process(bigData);
bigData = bigData.next;
}
into
BigData tmp = bigData;
while (tmp != null) {
process(tmp);
tmp = tmp.next;
}
bigData = null;
if the bigData
field is not volatile
and the process
method has no side-effects that forbid this optimization.
But in practice, the code transformation, if any, will look completely different. It’s typical that optimizers do loop unrolling, creating a code block performing a certain number of iterations and do the field storage operation before taking a backwards jump. So there are certain “savepoints” where the garbage collector can jump in. But if the process
method contains code that accesses the bigData
field or might allocate memory, etc, the field storage will be performed before every invocation.