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
Related
Finalizer thread are responsible clearing objects in the finalization queue. Ironically does the same finalizer thread can responsible for OOM?
Short answer: theoretically yes.
More specifically it depeneds on how your finalizer thread is constructed and what he does. In general any new object creation can lead to OOM if no free memory left.
The short answer is yes.
Some classes implement the Object.finalize() method. Objects which override this method need to called by a background thread call
finalizer, and they can't be cleaned up until this happens. If these tasks are short and you don't discard many of these
it all works well. However if you are creating lots of these objects and/or their finalisers take a long time,
the queue of objects to be finalised builds up. It is possible for this queue to use up all the memory.
If many objects with finalizers are created, it is likely that there will be performance issues,
even if the underlying native resources are explicitly freed using try-finalize blocks.
Code to try and outpace java garbage collector with finalizers showed the following result.
It is surprisingly easy to outpace the Java garbage collector if lots of objects with finalizers are created,
leading to spurious out-of-memory errors with lots of objects which could theoretically be reclaimed.More on this can be found on
the link http://www.enyo.de/fw/notes/java-gc-finalizers.html
There are some apps that have hit this finalizer queue build up problem in the past, so it is worth considering
how to deal with it. One obvious way is to increase the priority of the "Finalizer" daemon thread - there is no API for this,
so you have to run through all the threads to find it by name, then increase it's priority.
You could also take explicit control over finalization by removing the finalize() method and using your own explicit queue
using your own Reference objects in a very similar way that the Finalizer class processes the objects and their finalize()
methods . That way you control your finalization processing thread's priority and schedule.
Note that neither of these techniques reduce the overheads in having finalizable objects,
they just avoid the queue building up because of the lower priority thread.
How finalization works is shown in the link below for the curious
http://www.fasterj.com/articles/finalizer2.shtml
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.
Can anyone please tell me if we call garbage collector in parallel executing two threads, how many gc objects are created?
There's always only one garbage collector, that runs in it own Thread
There's one garbage collector as others pointed out.
You should not care about the count of the garbage collector objects
or about any details about the garbage collector. This is something
on JVM/system level. All you care about is when to call the garbage
collection explicitly (if you want to do that).
(This is responding to the OP's comments which reveal the nature of the misunderstanding that is at the root of his Question. See the quoted text ...)
yes Runtime is a singleton but when we are calling Runtime.gc(), ...
Correct
... the jvm internally it will created one thread that is garbage colletor(daemon thread).
Incorrect. It does not create a new GC thread. Rather it causes the existing GC thread to wake up and do a garbage collection. Furthermore:
the thread that calls gc() will not return until the garbage collector has completed.
depending on the garbage collector that has been configured, the garbage collector may freeze all other application threads before starting the collection.
... but in this case when we call gc in two different threads at a time, how many GC objects will be created?
None. If two methods call gc() at the same time, the GC will run once on the existing GC thread. Think of the GC as an "engine" that is either running or sleeping at any point in time. Calling gc() will typically cause the GC to start running if it is currently sleeping.
(Actually, I'm simplifying things a bit. CMS and G1 have the complication that the gc() will typically run in parallel with application threads. Another possibility is that the gc() call will be simply ignored. Finally, the GC typical has a variety of modes; e.g. a young generation collection, and a full collection. Calling gc() will start a full collection.)
... but we are saying that GC is daemon thread
Yes (sort of),
The GC may have multiple threads. There is typically a main GC thread, and another thread for handling finalization. And for some kinds of GC, some tasks are performed in parallel using a pool of threads.
and also gc() has native implementation
For mainstream JVMs, yes. (But as a counter-example, in JNode is implemented in Java, albeit using Unsafe methods, etc.)
then what is GC?
It is the "stuff" that does garbage collection. What actually goes on under the hood is JVM specific, and depends on JVM options, etcetera.
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.
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.