-
Bug
-
Resolution: Fixed
-
P3
-
1.1.4, 1.1.5, 1.1.6, 1.1.7
-
1.2alpha2
-
x86, sparc
-
solaris_2.5.1, solaris_2.6, windows_95, windows_nt
-
Not verified
Name: joT67522 Date: 11/11/97
/******
PROBLEM: Synchronously running the finalizer thread can cause deadlock
The finalizer and VM memory allocator can cause system deadlock under the following conditions:
1 - a finalize method calls a synchronized method
2 - a synchronized method which will block the finalize method in 1 causes an allocation failure
3 - the garbage collector tries to flush the finalizer queue
4 - the method from 1 blocks waiting on 2 (which is waiting on 1)
DEADLOCK
Environment: Java_1_1_final on NT4.0
NOTE: also reproduced on 1.1.3
MAJOR ISSUES:
This kind of problem comes up in the following real world scenario:
A missed ResultSet.close() results in the following sequence of calls:
sun.jdbc.odbc.JdbcResultSet.finalize()
sun.jdbc.odbc.JdbcResultSet.close()
sun.jdbc.odbc.JdbcOdbc.SQLFreeStatment() { which is synchronized }
****/
// a sample class to replicate VM GC lockup problem -- let it run for a little while
public class GCLock
{
public static void main(String[] argv)
{
GCLock factory = new GCLock();
factory.make();
}
public GCLock()
{
storage = new String[10];
allocateStorage();
System.out.print(".");
}
// keep creating objects with no references -- throw them away
public void make()
{
while(true)
{
new GCLock();
}
}
public void finalize()
{
System.out.print("/");
// call a synchronized "method"
releaseStorage();
System.out.print("\\");
}
private String[] storage;
private static Object allocator = new Object();
private void allocateStorage()
{
synchronized(allocator)
{
// spend some time inside a synchronized block that
for (int i = 0; i < storage.length; i++)
storage[i] =
new String("Now is the time for all good men to come to the aid of their country.");
}
}
private void releaseStorage()
{
synchronized(allocator)
{
storage = null;
}
}
}
/****************************
Below is the output of the above class run on NT4.0 - java 1.1_Final
........................................................................................................................
........................................................................................................................
........................................................................................................................
............................................................................./\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\.............
........................................................................................................................
........................................................................................................................
........................................................................................................................
.............................................................../
****** at this point the VM is locked up tight as a drum. NO OTHER THREADS WILL RUN!!!!
Full thread dump:
"Finalizer thread" (TID:0xf500d0, sys_thread_t:0x87b680, Win32ID:0xc4, state:MW) prio=2
GCLock.releaseStorage(GCLock.java:54)
GCLock.finalize(GCLock.java:33)
"main" (TID:0xf500a8, sys_thread_t:0x87bca0, Win32ID:0xc1, state:CW) prio=5
java.lang.String.<init>(String.java:124)
GCLock.allocateStorage(GCLock.java:48)
GCLock.<init>(GCLock.java:14)
GCLock.make(GCLock.java:24)
GCLock.main(GCLock.java:7)
Monitor Cache Dump:
java.lang.Object@F536E0/F9D190 (key=0xf536e0): "main"
Registered Monitor Dump:
Thread queue lock: <unowned>
Name and type hash table lock: <unowned>
String intern lock: <unowned>
JNI global reference lock: <unowned>
BinClass lock: <unowned>
Class loading lock: <unowned>
Java stack lock: <unowned>
Code rewrite lock: <unowned>
Heap lock: <unowned>
Has finalization queue lock: <unowned>
Finalize me queue lock: <unowned>
waiters = 1
Monitor cache expansion lock: <unowned>
Monitor registry: <unowned>
/*******/
company - LPA Software Inc. , email - ###@###.###
(Review ID: 13650)
======================================================================
The problematic finalize() method for us is ColorModel.finalize(). By looking at the stack traces for our deadlock cases (one of which is pasted below), it shows that this method is executing in the finalizer thread, and that it is waiting for a monitor lock on an instance of sun.awt.image.PixelStore8, which is already owned by the image fetching thread.
Therefore, let me outline the exact steps that are producing our deadlock, using the steps listed above:
1 - The image fetching thread obtains the monitor lock for an instance of sun.awt.image.PixelStore8, and then causes an allocation failure.
2 - the garbage collector tries to flush the finalizer queue.
3 - ColorModel.finalize(), via its calling chain, attempts to obtain the monitor lock for the sun.awt.image.PixelStore8 instance that is already being held in 1.
4 - the finalizer thread from 3 blocks waiting on 1 (which is waiting on 3)
DEADLOCK
- duplicates
-
JDK-4196038 finalizer deadlocks
-
- Closed
-
-
JDK-4135813 (refs) Deadlock of finalize and synchronised methods
-
- Closed
-
-
JDK-4089377 (refs) Deadlock during finalizer thread activation
-
- Closed
-
-
JDK-4116083 (gc) Garbage Collector deadlocks with class construction
-
- Closed
-
- relates to
-
JDK-4199515 Deadlock within the ColorModel's finalizer
-
- Closed
-