memory leaks caused by the Java Finalize MethodPosted:mon, Mar 2013 Java
Memory Dump
After the memory dump, a lot of memory (>5g) is Java.lang.ref.Finalizer hold (see Figure 1). And these memory is BDB occupy, suspect is bdb have memory leak (see Figure 2). java Finalizer mechanism
Why is the Java.lang.ref.Finalizer reference causing BDB to not be able to free memory. BDB no memory leaks on machines that do not have real-time indexing enabled? re-understand the Java finalize mechanism:
When you implement a Finalize object, the process of creating and recycling is more time-consuming. When created, creates an additional finalizer object that points to the newly created object. At least two times GC is required for recycling. The first GC, which detects that an object is only referenced by Finalizer, puts the object into Java.lang.ref.Finalizer.ReferenceQueue at this point, because the Finalizer reference, the object cannot be GC. Java.lang.ref.finalizer$finalizerthread will constantly clean up the object of the queue, remove the current element, and execute the object's Finalize method. After scavenging, the object does not have any references, and the next GC is reclaimed.
Finalizer positioning
Finally we found Java.lang.ref.finalizer$finalizerthread wait on a real-time indexed thread, see the following code.
A typical implementation of Java multithreaded synchronization://Cyclic check condition (cachedreadertimestamp <= begintime), each wait for a short period of time (200ms), up to the specified time (timeout)//
Another thread modifies the condition so that the condition is true (Cachedreadertimestamp > BeginTime) while (Cachedreadertimestamp <= begintime) {
Synchronized (cachemonitor) {cachemonitor.notifyall ();
LONG elapsed = System.currenttimemillis ()-begintime; if (Elapsed > Timeout)//elapsed may be equal to timeout {log.debug ("refreshcached
Reader timeout in "+ elapsed +" MS ");
throw new Zoieexception ("Refreshcached reader timeout in" + elapsed + "MS");
Long timetowait = Math.min (timeout-elapsed, 200); try {cachemonitor.wait (timetowait);//either awakened by another thread, or waits for timetowait; if timetowait is 0 o'clock, it can only be awakened by another thread, otherwise a
Straight wait} catch (Interruptedexception e) { Log.warn ("RefreshCache", e);
}
}
Code Review
Check the code found in the Mandy, there is a shutdown method is called two times to display the call, one is the first call in Finalize, the execution of the above code even if timetowait is 0, no problem, will be wired to wake the caller; The wake thread then exits as well. When the second finalize thread is invoked, execution of the above code timetowait to 0 o'clock, and the calling thread (Finalize thread) blocks all the time. Because the wake thread has exited the first time it was called. Fix
Remove the Finalize method to replay
Execute the following program java-xmx100m Finalize program never Stops
public class Finalize {
byte[] a = new BYTE[10 * 1024 * 1024];
protected void _finalize () {
synchronized (this) {
try {
this.wait (0);
} catch (Exception e) {
System.err.println (e);
}
}
public static void Main (string[] args) throws Exception {while
(true) {
new Finalize ();
Thread.Sleep (+);
}
}
After modification, implement Finalize method java-xmx100m Finalize
Quickly reported memory overflow error exception in thread "main" Java.lang.OutOfMemoryError:Java heap
protected void _finalize () {synchronized (this) {try {
This.wait (0);
catch (Exception e) {System.err.println (e); }}---> protected void Finalize () {synchronized (this)
{try {this.wait (0);
catch (Exception e) {System.err.println (e); }
}
}