Java set objects to null

clearing or set null to objects in java

Now in these case, if I call list = null; or list.clear(); , what happens to the objects? In which case the objects are lost and in which cases only the reference is set to null?

I guess it has to do with shallow and deep copying of objects, but in which cases does shallow copying happens and in which case does deep copy happens in Java?

7 Answers 7

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 list1 = new ArrayList(); ArrayList 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 list = new ArrayList(); Map map = new HashMap(); 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.

Источник

Garbage collector in java — set an object null

Lets assume, there is a Tree object, with a root TreeNode object, and each TreeNode has leftNode and rightNode objects (e.g a BinaryTree object) If i call:

what really happens with the related TreeNode objects inside the tree? Will be garbage collected as well, or i have to set null all the related objects inside the tree object??

6 Answers 6

Garbage collection in Java is performed on the basis of «reachability». The JLS defines the term as follows:

«A reachable object is any object that can be accessed in any potential continuing computation from any live thread.»

So long as an object is reachable 1 , it is not eligible for garbage collection.

The JLS leaves it up to the Java implementation to figure out how to determine whether an object could be accessible. If the implementation cannot be sure, it is free to treat a theoretically unreachable object as reachable . and not collect it. (Indeed, the JLS allows an implementation to not collect anything, ever! No practical implementation would do that though 2 .)

In practice, (conservative) reachability is calculated by tracing; looking at what can be reached by following references starting with the class (static) variables, and local variables on thread stacks.

Here’s what this means for your question:

If i call: myTree = null; what really happens with the related TreeNode objects inside the tree? Will be garbage collected as well, or i have to set null all the related objects inside the tree object??

Let’s assume that myTree contains the last remaining reachable reference to the tree root.

  1. Nothing happens immediately.
  2. If the internal nodes were previously only reachable via the root node, then they are now unreachable, and eligible for garbage collection. (In this case, assigning null to references to internal nodes is unnecessary.)
  3. However, if the internal nodes were reachable via other paths, they are presumably still reachable, and therefore NOT eligible for garbage collection. (In this case, assigning null to references to internal nodes is a mistake. You are dismantling a data structure that something else might later try to use.)

If myTree does not contain the last remaining reachable reference to the tree root, then nulling the internal reference is a mistake for the same reason as in 3. above.

So when should you null things to help the garbage collector?

The cases where you need to worry are when you can figure out that that the reference in some cell (local, instance or class variable, or array element) won’t be used again, but the compiler and runtime can’t! The cases fall into roughly three categories:

  1. Object references in class variables . which (by definition) never go out of scope.
  2. Object references in local variables that are still in scope . but won’t be used. For example:
 public List pigSquadron(boolean pigsMightFly) < ListairbornePigs = new ArrayList(); while (. ) < Pig piggy = new Pig(); . if (pigsMightFly) < airbornePigs.add(piggy); >. > return airbornePigs.size() > 0 ? airbornePigs : null; > 

It should be noted that the compiler / runtime can sometimes figure out that an in-scope variable is effectively dead. For example:

public void method(. ) < Object o = . Object p = . while (. ) < // Do things to 'o' and 'p' >// No further references to 'o' // Do lots more things to 'p' > 

Some Java compilers / runtimes may be able to detect that ‘o’ is not needed after the loop ends, and treat the variable as dead.

1 — In fact, what we are talking about here is strong reachability. The GC reachability model is more complicated when you consider soft, weak and phantom references. However, these are not relevant to the OP’s use-case.

2 — In Java 11 there is an experimental GC called the Epsilon GC that explicitly doesn’t collect anything.

Источник

Is it possible to set to null an instance of a class within the class

I have tried this and it does not work. Using «this = null» I get the error that the left hand side needs to be a variable. Is there a way to achieve something similar?

Any reason why you want to set it to null? Garbage collectors are smart. They know when an object is no longer reachable. Are you trying to kill all references to this object?

You’re trying to «destroy» the object. That cannot be done until ALL references to the object are gone. Best you can do is put a «deleted» flag in the object which causes all calls on it to fail.

@rioneye, the question really is why are you setting it to null. The objects inside the instance belong to the instance. The instance, if not rooted, is eligible for collection, along with its state. Is there more to this story of yours? Setting an object reference to null is generally not necessary.

@rioneye As soon as the method exits, the object will be eligible for GC if it was only referenced by a local variable.

«Instead of having multiple lines of code that remove all references within the class and set the object itself to null» — maybe this is your point of confusion. You don’t have explicitly null 99.9% of the references. Rather, they «go away» one way or another — the containing object is GCed, the containing method exits, etc. Only in a few cases (eg, a large array of references where objects may be «discarded» but still referenced from the array) do you need to explicitly null anything..

Источник

Is it possible to set an Object to be null from within itself?

I know that this = null is illegal. I’m wondering if there’s some other way to have an object clean itself up. my desire is to be able to do something like this:

A a = new A(); a.doStuffAndDisappear(); if(a == null) < //this is true after my doStuffAndDisappear() method. >

@MarcinOrlowski, It’s a little arrogant of you to declare this is «bad code» since there is no «code» just an idea! You might argue that such an approach might be entirely useless. I’d disagree. I have a self contained Widget that would be improved considerably if it could just make itself null after doing what it needs to do. Thus letting the GC clean it up and not leaving the Widget’s user to have to set it to null manually. Feels more OO to me, but as I said, we can differ on this.

@Dr.Dredel You are using «it» to refer to two very different things, an object and a specific reference to the object. In order to make the object available for GC you would need to change every reference to it that exists to null, not just the reference that was used in a specific call.

this , to the extent that is should be regarded as a reference, is merely one of the references. Even if you could stop an object from referring to itself, if any active thread has access to any reference that points to the object, it remains reachable and unavailable for GC.

7 Answers 7

No, because a is a reference (not an object as in this question’s title) and no method can modify the value of a reference except the method in which it is defined (I assume from the code context that a is a local variable).

Since Java doesn’t have pass-by-reference, what you ask cannot be done: there’s no way to collect addresses-of references in order to manage the addresses pointed to. You might use a wrapper object, but not sure what’d be the point.

As everyone else has said, this simply isn’t possible. If it’s cleaning up resources you’re after, then you might consider using a pattern such as:

class A < private boolean cleanedUp; public void cleanUp() < // clean up any resources cleanedUp = true; >public boolean isCleanedUp() < return cleanedUp; >> 

And then using it like so:

A a = new A(); a.cleanUp(); if (a.isCleanedUp())

A better solution might be to implement the java.io.Closeable or java.lang.AutoCloseable interfaces depending on your circumstance:

class B implements AutoCloseable < private boolean closed; public boolean isClosed() < return closed; >@Override public void close() throws Exception < // clean up any resources closed = true; >> 

In which case you can use a try-with-resources statement:

try (B b = new B()) < // do stuff >catch (Exception ex) < // oh crap. >

Or you could even combine the two and do it that way, whichever you prefer.

Or lastly you could do it the way William Morrison explained (though I’d probably cheat and just use java.util.concurrent.atomic.AtomicReference instead of making my own class, and it comes with the added benefit of being a generified type), which, depending on your circumstance, may really be unnecessary. After all, you could always just do (even though it might seem a little odd):

A a = new A(); a.doStuffAndDisappear(); a = null; if(a == null) < //. >

Источник

Читайте также:  Javascript вставить в input значение
Оцените статью