I'm just thinking about a way of keeping away Java objects from garbage collection even if it is not being referred for a reasonable amount of time.
How to do that?
Have a static container in your main class that you put a reference to the objects in. It can be a Map, List, whatever. Then you'll always have a reference to the object, and it won't be reclaimed. (Why you would want to do this is another question...)
Which is to say: As long as a reachable reference to an object exists, it will not be garbage-collected. If your code has a reference and tries to use it, the object will be there. You don't have to do anything special to make that happen (nor should you). (A reachable reference means that the reference is from something that is, itself, reachable from something other than the things it references. Put more simply: The GC understands about circular references and so can clean up A and B even if they refer to each other, as long as nothing else refers to either of them.)
[...] even if it is not being referred for a reasonable amount of time.
If there's any chance what so ever that an object will be accessed in the future, the object will not be garbage collected.
This is due to the fact that if you have a reference to the object, it won't be garbage collected, and if you don't have a reference to the object, there's no way you will be able to access it ever.
In other words, an ordinary reference will never mystically turn into a null just because the garbage collector observed that the object hadn't been accessed for a long time and thought it was time to reclaim it.
You could also create a static instance of the object in its own class. For example if it is a singleton, having a static instance field in the class.
There are mechanisms that will hold a reference to an object, but still allow it to be garbage collected, if there are no other references otherwise.
Look at WeakReference and SoftReference. If you want more details on reachability as far as the jvm is concerned, see:
http://download.oracle.com/javase/6/docs/api/java/lang/ref/package-summary.html#reachability
As far as time is concerned, the garbage collector doesn't know or care about how often an object is used. Either another object has a reference to the target (even if it's not using it), or there are no references to the target. If there are no references to the object, it could never be used again, and will eventually be freed (even if you wanted to, you couldn't obtain a reference to the object again) The longer-living an object is, the longer it takes for the jvm to free it, due to generational garbage collection.
I'm just thinking about a way of keeping away Java objects from garbage collection even if it is not being referred for a reasonable amount of time.
On the face of it, this question doesn't make sense. If an object is not referenced (or more a precisely, if it is not reachable) then the garbage collector will collect it. If you want to prevent an object from being garbage collected then you have to make sure that it is reachable. (Actually, it has to be strongly reachable to guarantee that it won't be GC'ed : see #Austen Holmes answer and the page that he references.)
But actually, I think that you are confusing "refered" / referenced / reachable with accessed or used; i.e. with the act of accessing a field or call a method of the object. If that is what you are asking, then I can assure that the garbage collector neither knows or cares whether your code has recently accessed / used an object.
The reachability criteria is actually about whether your code could access the object at some point in the future, and (therefore) whether the object needs to be kept so that this will work. The reachability rule means that if an object could be accessed, then it will be kept. It makes no difference how long it was since you last accessed it.
Related
Say i have a class, which loads a file and then calls another method to do something to that file. For example, counting the words in the file.
Within class CountWords, a number of objects/collections are created in order to get the number of words. The method runs, the number of words is found, and then this is returned to the calling class.
My question is, do all the objects/collection created in the CountWords class get "destroyed" when control is returned to the calling class or do they remain in the memory? If the latter, would i have to set each object to null before exiting the class to mark them for collection?
We don't generally control exactly when a Java object gets destroyed. It will get destroyed some time after it becomes inaccessible - in other words, when there are no further references to it in any scope.
If you create an object, and store a reference to it in a field of another object, then the object you created continues to be accessible for as long as the object that has the reference to it is accessible.
If you have code like this
public void run() {
Foo a = new Foo();
System.out.println("This method is finished");
}
then the Foo that you created will be inaccessible as soon as run finishes, because there are no more variables with references to it. Foo will be destroyed some time afterwards. Unless of course, the constructor of Foo does some magic to register itself in some nasty static data store somewhere.
So in general, you don't need to go round setting references to null to destroy objects. From the point of view of the garbage collector, letting those references go out of scope is just as good as setting them to null.
Java is a programming language that has memory management aka garbage collection. The basic answer is, the garbage collector will take care of reclaiming the memory of unused objects.
But since you have tagged the question with [garbage-collection], you should already know this. So it’s not clear what additional detail you want to know or why you think your scenario is special in any way, to deserve an additional answer beyond “there is a garbage collector”.
You question is full of phrases that are wrong or misguiding.
“do object references get destroyed”—the storage of objects is reclaimed, there is no such thing as “destruction of references”
“when the creating class is closed”—there is no such thing as “closing of classes”
“do all the objects/collection created in the CountWords class get ‘destroyed’ when control is returned to the calling class or do they remain in the memory?”—in this form, not simple to answer
there is no such thing as “destruction”. The whole purpose of garbage collection is to permit the reuse of the memory. This implies recording somewhere that the memory is free. But the memory itself does not need to be touched.
when your method returns, these objects are eligible for garbage collection. The garbage collection itself does not have to run immediately. It may happen when there is need for free memory or when the CPU load is low.
As said, even if the garbage collector ran, the result is that the memory is now considered to be free, not necessarily to “scrub” the memory. So the objects may “remain in the memory” until actually being overwritten by other objects. So that’s simply the wrong question. You actually want to know whether the memory will be reusable.
“If the latter, would i have to set each object to null before exiting the class to mark them for collection?”—“the latter” still implies that the memory is free, semantically. But what do you want to “set to null”? The references do not exist anymore. The objects are unreachable.
The answer is there is nothing you can do and there is nothing you should do. That’s the whole point of garbage collection, no need for you to do anything.
We don't need to set the objects to null after coming out the function . For this Java have garbage Collector , which runs on the Java Virtual Machine which gets rid of objects which are not being used by a Java application anymore. It is a form of automatic memory management.
For example :
for (int i =0 ; i<10 ; i++) {
String s = String.valueOf(i)
}
In the above code, the integer s is being created on each iteration of the for loop. This means that in every iteration, a little bit of memory is being allocated to make a integer object.
Going back to the code, we can see that once a single iteration is executed, in the next iteration, the integer object that was created in the previous iteration is not being used anymore -- that object is now considered "garbage".
Eventually, we'll start getting a lot of garbage, and memory will be used for objects which aren't being used anymore. If this keeps going on, eventually the Java Virtual Machine will run out of space to make new objects.
That's where the garbage collector steps in.
The garbage collector will look for objects which aren't being used anymore, and gets rid of them, freeing up the memory so other new objects can use that piece of memory.
Automatic memory management schemes like garbage collection makes it so the programmer does not have to worry so much about memory management issues, so he or she can focus more on developing the applications they need to develop.
I'd like to use a WeakReference as a more efficient finalize() method, for the purpose of freeing native resources associated with an object as soon as it becomes possible to do so, without using finalization (which has significantly higher costs than using a WeakReference).
Since this is the only purpose of the WeakReference (I will never use the WeakReference to obtain the referenced object), it seems wasteful to take the time and space to maintain a list of my WeakReferences to prevent them from being garbage collected.
But if a normal object is constructed and no strong reference is kept to it, it will simply be freed by the garbage collector, and I can't find anything in the Javadoc that suggests this is different for a WeakReference.
Is it necessary to keep a reference to a WeakReference to prevent it from being garbage collected, or, if it's to be enqueued in a ReferenceQueue, will that keep it alive until it's been collected from the queue?
Is it necessary to keep a reference to a WeakReference to prevent it from being garbage collected
Have a look at the java.lang.ref package description, it dedicates a whole paragraph to answering your question:
The relationship between a registered reference object and its queue is one-sided. That is, a queue does not keep track of the references that are registered with it. If a registered reference becomes unreachable itself, then it will never be enqueued. It is the responsibility of the program using reference objects to ensure that the objects remain reachable for as long as the program is interested in their referents.
I wanted to understand the below statement in bold. What does it means? (Link)
An object which overrides finalize() must now be determined to be
garbage in at least two separate garbage collection cycles in order to
be collected. When the first cycle determines that it is garbage, it
becomes eligible for finalization. Because of the (slim, but
unfortunately real) possibility that the object was "resurrected"
during finalization, the garbage collector has to run again before the
object can actually be removed. And because finalization might not
have happened in a timely fashion, an arbitrary number of garbage
collection cycles might have happened while the object was waiting for
finalization. This can mean serious delays in actually cleaning up
garbage objects, and is why you can get OutOfMemoryErrors even when
most of the heap is garbage.
What phantomreference solves
With PhantomReference, this situation is impossible -- when a PhantomReference
is enqueued, there is absolutely no way to get a pointer to the now-dead object (which is good, because it isn't in memory any longer).
Because PhantomReference cannot be used to resurrect an object, the object can
be instantly cleaned up during the first garbage collection cycle in which it is found to be phantomly reachable.
Please help me understand the problem & the solution
Thanks
Contrary to popular belief, finalize methods are not triggered when their associated objects are garbage-collected, but rather when their associated objects would have been garbage-collected but for the existence of their non-default finalize methods. Objects cannot actually be garbage-collected until the system can be 100% certain that no reference to them will ever exist, but the act of running a finalize method creates a strong rooted reference to the object in question which will exist at least until the method exits. If during the execution of finalize a reference to the object gets stored elsewhere, that reference could continue to exist indefinitely. Consequently, no object whose finalized method is going to be called, nor any other object to which such an object holds a direct or indirect strong reference, can be collected until after the finalize method has run and the next GC cycle confirms that no reference to the object exists anymore.
The PhantomReference class serves to encapsulate a different paradigm: rather than keeping an object alive so the system can notify it that it's been abandoned and the only reason it's still alive is so it can receive notification of abandonment, objects requiring cleanup should create helper objects to process notification of their abandonment. If the helper objects avoid keeping references to any outside objects they don't "own", their existence won't interfere with the collection of their parent object, or other objects to which the parents hold direct or indirect references. The helper objects generally won't hold enough information to let them "do much", but that's good because they shouldn't have to do much. Instead, their design should be focused on performing the cleanup that will be required if their parent is abandoned.
We all know that the JRE will destroy any object that can no longer be referenced. But is there a way for an object to explicitly destroy itself? Or is that forbidden to avoid the dangling pointer problem?
Naively, I would like to say this = null, but that is disallowed by the compiler (this is probably not a true variable anyway).
Conversely, is there a way for an object to forcibly keep itself alive, by maintaining private copies of this, or otherwise?
No. In fact, you cannot forcibly destroy anything. Even if you have no references to an object, it will continue to exist in memory until the garbage collector decides to run and collect it.
You could keep an object alive by keeping a static reference to it.
Ignoring the academic aspect, you can't ensure an object is physically destroyed in Java (or most any other garbage collected language, like C#). This is because destroying objects is expensive (partly because of the memory compression phase), so the point is to run it as few times as possible.
This said however, you can force an object to release its allocated resources using the disposable pattern, where the object in question exposes a public method to release resources, and you can call it at any time (or it gets called automatically in the finalizer). It requires a bit more bookkeeping, but it gets the job done if really needed.
No you can't destroy an object.
What you could do is have a wrapper object that holds the actual object. If you make sure that nobody else has a reference to that object removing the reference (e.g. by setting it to null) will make the object qualify for the garbage collector. Note that it is still up to the GC to decide when and if to actually collect the garbage.
In order to keep an object alive you need to make sure that there is a reference to it. One way would be to have a static reference from the class of the object. As long as nobody unloads the class your object will stay in memory.
As you said I think it is forbidden to avoid dangling pointer problems. Java memory model is based on Stack and Heap model, if an object destroys itself then what would go to stack (or) other pointers, which references the object?
I'm using the play framework. I want to keep alive one of my object everytime whether it is been used now or not because it will be used later.
Creating the object is a time taking process(contains 10L records). The object is gc'ed if it is not accessed for some time.
My idea is to access the object and keep it alive before it is gc'ed. I tried to access the object in a function with #Before annotation but it doesn't works. My primary idea is to keep alive of the object. If i know the after what time gc function is called then i can use job functionality in playframework to keep it alive.
The garbage collector will only clean up an object if there is no longer a reference to the object. Your design should ensure that this particular object exists and is referenced by at least one variable to ensure it is not removed during garbage collection.
You might want to investigate using a Singleton-style design pattern here, it will make sure there's a reference to the object, but that there's only ever one object at a time.
That way, the object will not be garbage collected as it's being referenced by at least one variable.
I hope this helps.
You seem to misunderstand how garbage collection works. If you're keeping a reference to your object around somewhere that you can hand it to a scheduled job, then that reference in itself will prevent the object from being collected. The only way this wouldn't apply is if you use a(n) (evil) singleton object to get a reference to the object in question, and periodically "touching" the object with a task won't inhibit garbage collection in that case. The simple solution there is to not use that (evil) pattern. The actual answer to your question is simply, "If you're not done with an object, then just don't let go of the reference to it." It's a quite natural solution.