I know how to leave a signal for the Garbage Collector to delete an object by setting its reference variable to null:
Player player_reference = new Player();
player_reference = null;
// Now the Garbage collector knows to release all the memory related to this object.
But how can I set the reference variable to null through the object's class?
class Player {
public void doSomthing() {
if(condition) {
// some code which set the reference variable to null.
}
}
}
I know how to leave a signal for the Garbage Collector to delete an object by setting his reference variable to null
That's not really a "signal" - it's just making sure that the variable in question doesn't prevent garbage collectio. You really, really need to be clear about the differences between variables, references and objects. This question is meaningless:
But how can i set the reference variable to null through the object class?
What reference? There could be multiple variables which all have values which are references to the same object. Or indeed there may be no such variables - you could be calling the method via some intermediate expression:
foo().bar().doSomething();
What variable you expect to be set to null in that case?
The object will be eligible for garbage collection when there's no way of getting to it any more in any thread. You don't need to manually delete it, or "signal" the garbage collector. It will just happen naturally.
Related
I'm confused with this program:
class Point {
private final int x;
private final int y;
}
public class App
{
WeakReference<Point> newPoint() {
Point referent = new Point();
return new WeakReference<Point>(referent); // after return, stack parameter referent is invalid.
}
public static void main( String[] args ) {
App a = new App();
WeakReference<Point> wp = a.newPoint(); // wp is hold valid or invalid reference?
System.out.println(wp.get()); // not null
}
}
I knew that if weak reference is pointing to an object that's no longer alive, its get() should return null. But in my code, seems its still alive.
Where did I get wrong?
I knew that if weak reference is pointing to an object that's no longer alive, its get() should return null. But in my code, seems its still alive.
Your understanding is imprecise, especially where it relies on the idea of aliveness. Reference objects in general and WeakReference objects in particular are not directly concerned with any of the senses of aliveness that I recognize. Rather, they are concerned with reachability.
The API docs for java.lang.Reference#get() (which is not overridden by WeakReference) say this:
Returns this reference object's referent. If this reference object has been cleared, either by the program or by the garbage collector, then this method returns null.
Note well that the condition for get() returning null is rather specific: the reference object has been cleared. This is achieved for a given instance by invoking that instance's clear() method. As the doc indicates, this may be done by the garbage collector or by the application.
Among the key differences between Reference subclasses is the conditions under which the garbage collector will perform such clearing. For WeakReferences, the API docs say:
Suppose that the garbage collector determines at a certain point in time that an object is weakly reachable. At that time it will atomically clear all weak references to that object [...].
Thus, until the garbage collector determines that a given object is (only) weakly reachable, it will not clear weak references to that object. The garbage collector probably does not run at all during the brief run of your small program, and if it did run, it would be surprising for it to be timed correctly to observe the Point in question to be weakly reachable before the reference's get() method is invoked.
You could try forcing a GC run by invoking System.gc() at the appropriate place. I anticipate that doing so will result in the weak reference being cleared. That would be for demonstrative purposes only, however. Generally speaking, you should rely on Java to perform GC when appropriate, not force it.
I'm saving the previous value of a Java object. I (almost) understand references are strong, weak, etc. but I can't find an example that classifies my specific situation that is apparently referencing an out-of-scope object. (I've looked at a lot of posts on this subject.)
Is the Java reference aTestCopy to the out-of-scope array of objects aTest valid?
It's a shallow copy but is it subject to garbage collection thus I need a deep copy for it to work reliably every time? Or should the declaration of the new object aTest be placed outside the while with the "previous" copied object aTestCopy?
Is the use of a null a good practice for the first-time-through switch or should that be a separate boolean variable?
Thanks.
Tester[] aTestCopy = null;
while(true)
{
Tester[] aTest = myMethodReturnsATesterArray(); // new values
// need code to skip using aTestCopy the first time through - no previous value
// else use the previous value here
aTestCopy = aTest; // save them for the next use of previous values
}
There is no problem to use null as initial value for reference types in Java. But there isn't any relevance between initialize a reference type as null and garbage collection. You should initialize aTestCopy as null to use in another scope like in your case in while.
Garbage collection is triggered whenever an object in memory is not pointed anymore by any reference.
When you assign a reference type to another reference type (if it is not immutable in this case), you made copy the memory address of that value. So when you can make a change in aTestCopy will be reflected to the reference aTest.
In Java, variables do not hold objects, only references to objects.
The lifetime of objects is largely independent of the lifetime of variables: Objects are created by executing new, and reclaimed once the program has relinquished all means of accessing them (i.e. the object is no longer reachable form the references the program holds).
Put differently, the first variable to hold a reference to an object holds no special significance. In particular, it does not determine the lifetime of that object. Any reference will keep the object alive, and there can be no such thing as an "out of scope" object.
Similarly, when you assign a variable of reference type, you are only assigning the reference, causing both variables to point to the same object, and to see any changes done to this object though the other variable.
If you want a new object, you must use new (or call a method that uses new).
In your case, I'd make sure that myMethodReturnsATesterArray returns a new array, referencing new Tester objects. Then, the objects created by separate iterations of the loop will exist independently, allowing the loop to reference both the old and new objects and do whichever comparision it deems appropriate, without having to fear that the invocation of myMethodReturnsATesterArray has somehow changed the previous object.
I sometimes see the code of this kind in some library APIs and just in someone's code:
class SomeClass {
private WeakReference<SomeObject> objectWeakReference; // initialized elsewhere
public boolean isObjectAttached() {
return objectWeakReference.get() != null;
}
public SomeObject getObject() {
return objectWeakReference.get();
}
}
and
public void checkAndGetWeakReference() {
SomeClass someClass = new SomeClass();
if (someClass.isObjectAttached()) {
someClass.getObject().doSomethingDirectlyOnReturnedObject(); // can the returned reference be null here ?
}
}
And I'm always worried if there could be NullPointerException once in a blue moon, assuming there are no strong reference to the underlying object at this point.
I don't really know when exactly Garbage Collector can start deleting objects from memory and how does it correlate with the basic thread flow.
It would be nice if someone can shed the light on this particular subject and/or provide some information about the topic.
P.S. I would personally get reference only once and assign it to strong reference. The point of the question is to get some proof the code above is wrong.
The whole point of the WeakReference (and SoftReference as well) is that the referred object may be gc'd at any time no strong reference to the object exists.
Since there exists no strong reference when isObjectAttached() returns, yes it can be garbage collected before it actually gets to execute getObject(). The whole idom is faulty for this use case.
The only safe way is to first get the reference (e.g. to a local variable) and then check it against null. The object can then not be garbage collected in that case, because a local variable is a strong reference.
As per java doc. You should not rely on Garbage collector. Its not sure when it will be executed. Though you are trying explicitly System.gc()
Its always been a lowest priority for JVM for garbage collector. When JVM is free or when your program is around to ran out of memory it can execute GC.
In other case when your program will exit. It will be garbage collected before it is flushed out of JVM memory.
Please refer javadoc for detailed explanation for GC.
http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html
I would like to add something to all answers.
Your object can be null when you call below method :
public SomeObject getObject() {
return objectWeakReference.get();
}
about garbage collection of this object.
If you do something like below :
public static void main(String args[]) {
SomeClass oSomeClass = new SomeClass();
// this one is strong reference "obj"
// this object can be null. Best practice is to null check before you use it.
// Or i will suggest to call isObjectAttached() method before you use it
Object obj = oSomeClass.getObject();
}
When you do obj = null; somewhere in code after above statement.
This object memory is available for garbage collection. Whenever JVM feels to clean memory. Yes it can collect this object.
Regarding proof of code you are asking.
public boolean isObjectAttached() {
return objectWeakReference.get() != null;
}
This method is made for you to check whether this object is present in memory or it has a valid reference for you.
If it returns true you will never get nullpointer exception.
but if you are not using this method i will suggest to use null check always before you use your object.
Hope I am on right direction and making some sense in my answer. Please respond accordingly.
We all are here to learn ;-)
Enjoy Java, OOP concepts.
Garbage collector internally has its heuristics to collect soft/weak/phantom references. It will not collect those objects in subsequent GC calls. It tracks these objects until it reaches the threshold of that heuristics, GC is not allowed to collect these references.
You have one big object in java. it has got 4 or five references. you don't know all those references. At time on deletion you know only one reference and you want to delete that object completely. How to achieve that? and also if you want to know other references then to what is the best way to do that.
It is not in our hand.. You can just nullify it from your end..
Object a = new Object();
a = null; // after that, if there is no live thread which is accessing members,it will be deleted by garbage collector
You could try Finalize() or System.runFinalization() but frankly, if there are references still pointing to the object, then I think the GC will ignore your request.
It is not possible in Java.
If you have strong reference referring your object, you cannot force JVM to GC that object. It simply cannot guarantee the program will work.
If codes of all other references are in your control, consider changing them to use WeakReference or SoftReference
There are some things that are not in our hands and its better to leave it to the JRE to handle it. All we can do that we make sure that the we make them null explicitly after using them.
{
// Some block
HugeObject obj = HugeObject.getInstance();
// Use it
obj = null;
}
// end of block
Java memory handling is just built to prevent that. An object is guaranteed to live as long as a reference to this object exists. As far as I know there is no (official) way to get to know the other references to an object (and there should be no need for that).
In Java GC(Garbage collector) handles heap cleanup. If an Object has no live references to it then it will automatically be cleaned up. So you need to make sure there are no live references to the Object.
Making it null is one of the way. But it will not guarantee it's cleanup if there is some other Object pointing to the same reference. That is why writing good code involves closing all the resources after use which includes making it to null.
If you are running low on heap you can try increasing heap size or calling System.gc() but again calling gc manually does not guarantee gc will actually be performed. it depends on lot of parameters which are JVM dependent.
What kind of references are these to the object? Are these references created by you and at runtime you don't keep track of of those references. If this is the case, you can wrap your references to the object in soft/ weak reference and then explicitly run the GC request. Otherwise, on runtime, if any live thread has access to the object. GC shall not delete that object.
It is hard to answer no knowing your use case, but if there is one location that you want to be able to remove it from then you can store every other reference to it as a WeakReference. Java normally uses strong refrences when referencing objects and the GC will only clear something when it has no more strong references. However, if you use WeakRefrences and your strong refrence ever goes out of scope there is no guarantee that your data will remain even if it is still needed.
I could be mistaken about this though, as I haven't used this class in a year or two.
On WeakReferences:
http://docs.oracle.com/javase/7/docs/api/java/lang/ref/WeakReference.html
You can declare your objects as WeakReference and add them in ReferenceQueue. In this way , whenever your object will not be further referenced , it will be liable for GC.
/**
Initialize the reference queue , even if you don't do it , no problem . Default reference queue will be taken.
**/
ReferenceQueue<? super Object> testReferenceQueue = new ReferenceQueue<Object>();
Map<String,String> demoHashMap = new HashMap<String,String>();
demoHashMap.put("SomeValue","testValue");
// Declare the object as weak object and put it in reference queue
WeakReference<?> weakObject = new WeakReference<Object>(demoHashMap,testReferenceQueue );
demoHashMap.clear();
demoHashMap = null; // This object is not referenced from anywhere
if(weakObject!=null){
System.out.println("Object is not GCd yet");
}else{
System.out.println("It is already garbage collected");
}
In Java, what is an unreachable object? When does the object become unreachable? While studying garbage collection I was not able to understand this concept.
Can anyone give any ideas with examples?
When there are no longer any reference variables referring to it, OR when it is orphaned in an island.
An island being an object that has a reference variable pointing to it, however that object has no reference variables pointing to it.
class A { int i = 5; }
class B { A a = new A(); }
class C {
B b;
public static void main(String args[]) {
C c = new C();
c.b = new B();
// instance of A, B, and C created
c.b = null;
// instance of B and A eligible to be garbage collected.
}
EDIT: Just want to point out that even though the instance of A has a reference, it is on an island now because the instance of B does not have a reference to it. The A instance is eligible for garbage collection.
An object is unrechable when there are no more references to it, or those references are themselves from unrechable objects.
Integer i = new Integer(4);
// the new Integer object is reachable via the reference in 'i'
i = null;
// the Integer object is no longer reachable.
in the object graph when one is not linked to it, then the reference become unreachable. then then the garbage collector scans for these dangling orphan objects and swipe out regaining allocated memory.
java.lang.ref.{Phantom,Soft,Weak} Reference Enqueues unreachable objects.
If the finalizer is run, the GC already knows its unreachable.
read about finalization- http://java.sun.com/developer/technicalArticles/javase/finalization/
In a language which has only strong references, heap objects can either be reachable or unreachable from the
program. The set of reachable objects is determined by the set of class variables and method variables in the program
pointing to heap objects. This set is usually referred to as the root set of the program. An object pointed by a variable
in the root set of the program is reachable. In addition, an object might be indirectly reachable. That is, an object is
reachable if there is another reachable object pointing to it. Such chain of references from the root set of the program
to a heap object is called reachability path. An object may have more than one reachability path to it as well as have
no reachability paths at all. If the object has no reachability paths it is deemed garbage and can be immediately
collected by the garbage collector.
An object enters an unreachable state when no more strong references to it exist. When an object is unreachable, it is a candidate for collection. Note the wording: Just because an object is a candidate for collection doesn't mean it will be immediately collected. The JVM is free to delay collection until there is an immediate need for the memory being consumed by the object.
It's important to note that not just any strong reference will hold an object in memory. These must be references that chain from a garbage collection root. GC roots are a special class of variable that includes
Temporary variables on the stack (of any thread)
Static variables (from any class)
Special references from JNI native code
more if you like to http://java.sun.com/docs/books/performance/1st_edition/html/JPAppGC.fm.html
An unreachable object, is an object that doesn't have a "reachable" reference to it.
In other words, no references to it.