You ask a question with the wrong premise. Since the == operator does not compare memory cells, it is not wise to change the memory location as such. The == operator, applied to links, compares the identity of the objects mentioned, regardless of how the JVM implements it.
To name an example that counteracts conventional understanding, a distributed JVM can have objects stored in RAM on different computers, including the possibility of local copies. So just comparing addresses will not work. Of course, its implementation of the JVM ensures that the semantics defined in the Java Language Specification are not changed.
If a particular JVM implementation implements link comparison by directly comparing memory locations with objects and has a garbage collector that, of course, can change memory locations, down to the JVM, to ensure that these two functions cannot interfere with each other in an incompatible way.
If you are wondering how this might work, for example. inside optimized JIT-compiled code, granularity is not as good as you might think. Each sequential code, including advanced branches, can be considered executed fast enough to delay collection of garbage until it is completed. Thus, garbage collection cannot happen at any time inside optimized code, but must be allowed at certain points, for example.
- reverse branches (note that due to the unfolding of the loop, not every iteration of the loop implies a reverse branch)
- memory allocation
- thread synchronization actions
- calling a method that has not been embedded / parsed
- maybe something special i forgot
Thus, the JVM emits code containing certain “safe points” at which it is known, which links are currently stored, how to replace them if necessary, and, of course, changing locations does not affect the correctness. Between these points, the code can work without worrying about the possibility of changing the location of the memory, while the garbage collector will wait for the code to reach a safe point, when necessary, which is guaranteed to happen in a finite, fairly short time.
But, as said, these are implementation details. At the formal level, things like changing the location of a memory do not exist, so there is no need to explicitly indicate that they are not allowed to change the semantics of Java code. No implementation details are allowed to do this.