Search code examples
javagarbage-collectionjava-threadsjava-memory-model

Java Instance Variable referred within local variable. Memory, thread safety and finalization


I have class MyClass which has a method with variable - an instance of OtherClass as shown below

public class Myclass{ 
   public void meth1(){
 
  OtherClass other = new OtherClass();  
    other.perform();
     
    }

}

public class OtherClass{

private Map<String, String> ops = new HashMap<>();

public void perform(){

  // put/ remove values in ops 
    }

} 

This is a multi-threaded environment When a thread executes the method meth1() where does Map is created? in heap? Is there thread safety issues wrt to the map declared as instance variable. When local variable is garbage collected, I assume map is also garbage collected. Please correct if I am wrong.

Note: I know there are data corruption when we have instance variables within multi-threaded environment However this is slightly difference scenario


Solution

  • When a thread executes the method meth1() where does Map is created? in heap?

    Yes. Everything you create with new Whatever() is stored on the heap, both the OtherClass instance as well as its HashMap (as its initialization includes the new HashMap<>() expression). And everytime you execute new Whatever(), you get a completely fresh instance on the heap.

    Is there thread safety issues wrt to the map declared as instance variable.

    No, not in your example. Only if multiple threads were accessing the same instance of OtherClass, thread safety might become an issue. In your case, every thread of execution creates its individual OtherClass instance (in the local variable other), uses only that one, and does not hand it out to any place where another thread might see it.

    When local variable is garbage collected, I assume map is also garbage collected.

    Yes, as long as you don't add code that hands the Map out to some other part of the software.

    Instances are garbage collected when they are no longer referenced by any "live" variable/parameter/object/... In your case, the ops HashMap is only referenced (stored) by the ops field of its enclosing OtherClass instance. So, when this instance is no longer reachable, the Map becomes unreachable as well, and thus ready for garbage collection.

    One remark: the garbage collection won't happen the very same moment when something becomes unreachable, it's scheduled by some elaborate optimized algorithm. The only thing you can be sure of is that it'll happen before you run out of memory.

    Note: I know there are data corruption when we have instance variables within multi-threaded environment However this is slightly difference scenario

    That's true only the opposite direction: You can't run into thread safety / data corruption issues if you don't have instance or class fields.

    True is: If you use instance or class fields in a multi-thread setting, you have to be careful. But e.g. read-only instance fields (ones that you only set in the constructor and never change later) are generally safe.