clearing or set null to objects in java

前端 未结 7 1624
盖世英雄少女心
盖世英雄少女心 2020-12-09 09:18

I was recently looking into freeing up memory occupied by Java objects. While doing that I got confused about how objects are copied (shallow/deep) in Java and how to avoid

相关标签:
7条回答
  • 2020-12-09 09:33

    Java GC automatically claims the objects when they are not referenced anywhere. So in most cases you will have to set the reference as null explicitly

    As soon as the scope of the variable ends the object becomes eligible for GC and gets freed up if no other reference points to the object.

    Java is pass by value so if you set the list as null in the method then it will not affect the original reference that was passed to you in the method.

    public class A{
    
        private List<Integer> list = new ArrayList<Integer>();
        public static void main(String[] args) {
           A a = new A();
           B b = new B();
    
           b.method(a.list);
    
           System.out.println(a.list.size()); //Will print 0 and not throw NullPointerException
        }   
    
    }
    
    class B{
        public void method(List<Integer> list){
            list = null;
            //just this reference is set to null and not the original one
            //so list of A will not be GCed
        }
    }
    
    0 讨论(0)
  • 2020-12-09 09:38

    I was recently looking into freeing up memory occupied by java objects.

    A piece of advice.

    It is usually a bad idea to think about this. And it is usually a worse idea to try to "help". In 99.8% of cases, the Java garbage collector is able to do a better job of collecting the garbage if you actually just let it get on with it ... and don't waste your effort by assigning null to things. Indeed, the chances are that the fields you are nulling are in objects that are about to become unreachable anyway. And in that case, the GC is not even going to look at the fields that you've nulled.

    If you take this (pragmatic) view, all your thinking about shallow versus deep copies and when it is safe to null things is moot.


    There is a tiny percentage of cases where it is advisable to assign null ... to avoid medium or long term storage leaks. And if you are in one of those rare situations where it is "recycling" objects is actually a good idea, then nulling is also advisable.

    0 讨论(0)
  • 2020-12-09 09:39

    If you passed an ArrayList to a method then list = null will have no effect if there is a live reference to the list somewhere eg in the calling code. If you call list.clear() anywhere in the code the references to the objects from this list will be nulled. Passing a reference to a method is not shallow copying it is passing reference by-value

    0 讨论(0)
  • 2020-12-09 09:40

    Firstly, you never set an object to null. That concept has no meaning. You can assign a value of null to a variable, but you need to distinguish between the concepts of "variable" and "object" very carefully. Once you do, your question will sort of answer itself :)

    Now in terms of "shallow copy" vs "deep copy" - it's probably worth avoiding the term "shallow copy" here, as usually a shallow copy involves creating a new object, but just copying the fields of an existing object directly. A deep copy would take a copy of the objects referred to by those fields as well (for reference type fields). A simple assignment like this:

    ArrayList<String> list1 = new ArrayList<String>();
    ArrayList<String> list2 = list1;
    

    ... doesn't do either a shallow copy or a deep copy in that sense. It just copies the reference. After the code above, list1 and list2 are independent variables - they just happen to have the same values (references) at the moment. We could change the value of one of them, and it wouldn't affect the other:

    list1 = null;
    System.out.println(list2.size()); // Just prints 0
    

    Now if instead of changing the variables, we make a change to the object that the variables' values refer to, that change will be visible via the other variable too:

    list2.add("Foo");
    System.out.println(list1.get(0)); // Prints Foo
    

    So back to your original question - you never store actual objects in a map, list, array etc. You only ever store references. An object can only be garbage collected when there are no ways of "live" code reaching that object any more. So in this case:

    List<String> list = new ArrayList<String>();
    Map<String, List<String>> map = new HashMap<String, List<String>>();
    map.put("Foo", list);
    list = null;
    

    ... the ArrayList object still can't be garbage collected, because the Map has an entry which refers to it.

    0 讨论(0)
  • 2020-12-09 09:45

    It depends on how many variables are referenciating to each of your objects, to explain this it would be better some code:

    Object myAwesomeObject = new Object();
    List<Object> myList = new ArrayList<Object>();
    
    myList.add(myAwesomeObject);
    
    myList = null; // Your object hasn't been claimed by the GC just yet, your variable "myAwesomeObject" is still refering to it
    
    myAwesomeObject = null; // done, now your object is eligible for garbage collection.
    

    So it doesn't depend whether you pass your ArrayList as an argument to a method or the like, it depends on how many variables are still refering to your objects.

    0 讨论(0)
  • 2020-12-09 09:51

    To clear the variable

    According to my knowledge,

    If you are going to reuse the variable, then use

                   Object.clear();
    

    If you are not going to reuse, then define

                   Object=null;
    

    Note: Compare to removeAll(), clear() is faster.

    Please correct me, If I am wrong....

    0 讨论(0)
提交回复
热议问题