I have some question over here regarding the java garbage collector.
First let me clear what I have understood regarding the Java GC.
GC is a background thread will always run in the background when the JVM starts.
Each object having one finalize() method. This method is used to release the
system resources before the object is destroyed. According to java experts,
we should not put the resources under finalize() method for releasing the
system resources. Becuase we cannot make sure when the GC will run. But we can
request the GC to run by calling System.GC().
So now my question is, GC is a background thread will always run in the background.
Now how can we say that we dont know when the GC will run? Is the statement like this "we dont know when the GC will call finalize() method "
Is that the meaning of that? If that is what they meant, then what is the job
of GC? GC's responsibility to find out the un used variable and remove from the memory.
In that case,why GC cannot call finalize() method also?
Now how can we say that we dont know when the GC will run?.
Functioning of GC is dealt by complex Algos, which is dependent on underlying OS and Hardware. WE can't say because if one tell about a particular JVM version it will not be valid with other JVMs. So it better we can't rely on that.
what is the job of GC.
GC finds reference less objects (read type of ref. for more) and reclaims memory used by them.
n that case,why GC cannot call finalize() method also?
So that's sure finalize method will be called but it's not sure when. Because evenif you know in your JVM when finalize() method will run, you never know when in other JVMs. So, if you deal with some really expensive resources in your finalize method, your programe may crash in other JVMs.
Simply put, GC will run at an indeterminate time, so system resources would not be freed in a timely manner if finalize is relied on to free them. It doesn't make sense to wait for the GC to reap the heap space of an object holding a system resource when most program logic should be easily designed to simply release the resource when it is no longer in use.
On a somewhat related note. One of the issues that caused early versions of the JVM to be so slow was calling finalize. Thus, modern JVMs will skip calling finalize whenever possible. So relying on finalize could also have a performance impact.
Related
I know that the garbage-collection is used to get rid of the orphaned objects (the ones that loses their references) but is it possible to set custom intervals for garbage-collecting in Java?
It is not advisable for an application to tell the GC to run. It is better to leave it to the JVM to make the decision.
Why?
Because the JVM knows best. The JVM has access to information that allows it to run the JVM at the best time, to optimize either for high throughput or low pause times. It can monitor the size of the various heap "spaces", and estimate the best time to initiate a collection, and what kind of collection to initiate. The decision making is complicated.
By contrast, if an application calls System.gc() on a fixed time interval, it may run when it doesn't need to, using CPU cycles unnecessarily. Indeed, if you run the GC when there is no garbage, it spend a lot of time scanning all of the live objects ... and then not achieve anything.
The other thing to note that if System.gc() is not ignored, a common behavior is to run a full garbage collection. Depending on your JVM's GC options, this may cause all application threads to be frozen. If the heap is large, the "GC pauses" for full collections can be significant.
Another answer suggests using the sun.rmi.dgc.client.gcInterval property. This is designed to deal with the collection of remote references in an RMI application. It may work in other contexts, but it is inadvisable for the reasons stated above.
Using Runtime.getRuntime().gc() or System.gc() you can suggest JVM for garbage collection but you cannot set intervals or call it in any way
public static void gc()
Calling the gc method suggests that the Java Virtual Machine expend effort toward recycling unused objects in order to make the memory they currently occupy available for quick reuse. When control returns from the method call, the Java Virtual Machine has made a best effort to reclaim space from all discarded objects.
The whole point of a garbage collection is, that the developer does not need to worry about the memory management whatsoever (as always there might be exceptions, but these are rare)
As pointed out you can only suggest the JVM to trigger the GC from your java code.
If you have problems with your GC interval, maybe you can instead set some parameters to your JVM?
Maybe you can use the parameter:
gcInterval(ms) = max interval between GC
But I have never used it myself, so no experience on this one.
As there are so many objects being created for a particular class some of which could be referenced and some can be anonymously lying in the heap and hence elgible for garbage collection . So is the presence of even one non referenced object in the heap is enough for garbage collector to run or is there any other criteria to assure the garbage collector is executed.
Thanks
Jayendra
we don't know when GC get executed, it depend on lots of things e.g. Type of GC. Also you can recommend to VM to launch GC by doing System.gc(). But again it is just a recommendation
GC on an object is, for typical reference implementations of the JVM, completely non-deterministic. There is no way to guarantee when, or even if, the GC will be run, never mind if it will result in a particular object reference being released (and its corresponding finalizer called.) This is regardless of the state of this particular object.
As pointed out in comments, System.gc() is merely a hint or request. In a great many cases it will result in a full GC. But consider gathering a heap dump usually results in 2-3 calls to System.gc() before the dump is generated, mostly as a way to improve the chances it actually happens.
There are experimental VMs that offer various implementations of real-time guarantees where some of this is not true.
My application makes use of a third-party library (the JTDS driver) that has some objects that override the finalize() method. I think they obey all the rules about when not to use finalize() - it doesn't depend on them running in a timely manner or at all.
The problem is that they objects are never being released. They seem to get stuck in the Finalizer queue and never removed. They build up slowly over a couple of weeks and run the JVM out of heap space. Thread dumps show the Finalizer thread just waiting for something to call finalize() on. If I call System.runFinalization(), the objects are finalized and are properly removed from the finalizer queue (and don't show up in heap dumps anymore).
Why will System.runFinalization() remove objects properly, but the Finalizer thread won't do it on its own?
Had the same issue today. You are not specifying what JVM you are using but just in case it is OpenJDK - there is a bug https://lists.launchpad.net/openjdk/msg10021.html
They say it is already fixed so you just need to upgrade.
This means your finalize() methods are taking too long resulting in objects building up in the queue waiting to be called.
Objects are removed from the queue as they are being called and wont be in the queue after being called.
Why won't the Finalizer thread remove these objects?
The simple answer is, something in side the finalizer has caused a deadlock. Finalizers are the worst way to do clean-up. It is called by the garbage collector.
Called by the garbage collector on an object when garbage collection
determines that there are no more references to the object.
What happens when the object to be garbage collector has a strong reference? The object never gets garbage collector. I strongly doubt this is what is happening in your case.
Joshua Bloch says in Effective Java:
In summary don't use finalizers except as a safety net or to terminate
noncritical native resources
Avoid finalizers - Finalizers are unpredictable, often dangerous, and generally unnecessary
http://www.informit.com/articles/article.aspx?p=1216151&seqNum=7
Let's say I'm writing an API in java that refers to some native C libraries, that requires destructors to be called explicitly. If the destructors are not called, I run out of native memory.
Is there a way to protect users of my API from calling the destructors explicitly, by having the garbage collector call the destructors somehow? (perhaps based on some estimate I make of the size of the used native memory?)
I know Java doesn't have its garbage collector as part of the Java API, but perhaps there is some way to get this implemented?
One alternative if you have control over creation of your objects is to reference them with a WeakReference using the constructor that takes a ReferenceQueue. When they get out of scope, the Reference will be queued and you can have your own thread polling the queue and call some clean up function.
Why?
Well, it is slightly more efficient than adding finalizers to your classes (because it forces the gc to do some special handling of them).
Edit: The following two (variations of the same article) describes it:
http://java.sun.com/developer/technicalArticles/javase/finalization/
http://www.devx.com/Java/Article/30192
Peter Lawrey has a very good point when he says:
Even so, waiting for the GC to cleanup can be inefficient and you may want to expose a means of explicitly cleaning up the resource if its required.
Whenever you can assume your users to be on Java7, take a look at java.lang.AutoCloseable as it will help them do that automatically when using the new try-with-resources.
In addition to use finalize(), you may need to trigger a GC if you run out of resources to make the call, however a GC hasn't been run.
The ByteBuffer.allocateDirect() has this issue. It need the GC to clean up its ByteBuffers, However, you can reach your maximum direct memory before a GC is triggered, so the code has to detect this and triggers a System.gc() explicitly.
Even so, waiting for the GC to cleanup can be inefficient and you may want to expose a means of explicitly cleaning up the resource if its required.
Garbage collector will call finalize() of Java objects when the Java object is about to be GCd, and inside the finalize, you could call the destructor. Just make a new Java object for every destructor that needs to be called, and keep reference to that Java object until when you want to call the destructor.
In practice, finalize() will be called sooner or later (even though technically Java makes no guarantee that any particular object will ever be GCd). The only exception is if the object is still around when the process is shutting down: then it may indeed never get GCd.
Java automatically calls garbage collector, then why we need manual calls for garbage collection? When should use System.gc()
Java automatically calls garbage collector, then why we need manual calls for garbage collection?
We don't need them. Indeed, in most circumstances calling System.gc() is harmful for application performance. See my answer to "Why is it a bad practice to call system gc" for a detailed explanation.
When should use System.gc()
If the application knows it is going into a phase where it has nothing else to do AND the user is unlikely to notice a garbage collection, then maybe it is OK call to System.gc() in an effort to stop the user experiencing GC pauses in the future.
The downsides include:
Calling System.gc() typically triggers a full GC which takes significantly longer than a GC of the 'new space'.
The user may actually care / notice. For example, if you call System.gc() between "levels" in a game, you make loading the next level take longer.
By forcing the GC, you are causing the JVM to use extra CPU cycles, etc which may potentially interfere with other things that the user is doing on his machine.
(There can also be legitimate reasons to call System.gc() in unit tests, and during system debugging.)
There isn't a need to call for garbage collection explicitly and calling System.gc() is only a suggestion, the JVM can ignore your suggestion.
The only practical uses I can think of is
During debugging, forcing a collection can expose a memory leak
If the program goes through predictable cycles of intense computation followed by no computation (like a turn based game), during the no-computation period the CPU could be utilized for a suggested garbage collection to prevent jitter during the intense computation portions.
System.gc() is only a suggestion. But it does make sense in some situations.
Suppose you have class MyClass, and you're wondering how much memory does one instance take. What you can do is this (roughly speaking):
MyClass [] objects= new MyClass[100000];
System.gc();
long memoryNow = Runtime.getRuntime().freeMemory();
for (int i = 0; i < 100000; i ++) {
objects[i] = new MyClass();
}
System.gc();
long memoryLater = Runtime.getRuntime().freeMemory();
int objectSize = (int)((memoryLater - memoryNow) / 100000);
There are other similar cases I've found System.gc() to be useful.
One aspect not yet mentioned is that some types of objects may ask entities outside themselves to do things on their behalf (e.g. give them exclusive access to a non-fungible resource like a file), to the detriment of other entities. When a garbage-collection is performed, the system will not only free up memory that was formerly occupied by unreachable objects, but it will also call finalize on objects that it notices have been abandoned, thus allowing such objects to notify outside entities that their services are no longer required. It is entirely possible for a program to reach a state where there's plenty of memory, but a necessary resource is unavailable because an object has been granted exclusive access and has since been abandoned without releasing it. Forcing the garbage-collector to run in such a situation may sometimes free up the necessary resource.
The garbage collector is always called by the JVM when there is not enough memory to allocate new objects into the heap. While calling the garbage collector, it follows the Stop the World norms and for this it calls the System.gc() method.
Also remember that the JVM also runs parallel gc threads to remove unused objects from memory . So everything and every minute JVM maintains heap memory and always tries to not overload it. So there is no any requirement to explicitly call System.gc() or Runtime.gc() method.
If you want more detail about this you can get here for the relevant information.
Garbage collection process is not under the user's control.So it makes no sense to call System.gc(); explicitly. It entirely depends on the JVM.
Few days back, I had asked exactly the same question : [Here].
In fact, many questions related to calling System.gc(); explicitly have been already asked and answered here. Calling System.gc(); explicitly is always considered as poor programming skill, although it won't do any harm.
Here are the few links that I you should go through it. It will definitely clarify your doubt.
Calling System.gc(); explicitly
Bad practise - Calling System.gc();
System.gc(); in java
PS : Btw, you should seriously take
the extra effort to go through
similar StackOverflow questions before posting about your doubts.
There is no need to call System.gc() or Runtime.getRuntime().gc(). The JVM internally controls garbage collection if it finds that it is running out of memory.