Hi folks,
I'm trying to profile on monitor contention. But whatever combination of VM and switches I use the output remains meaningless, although there
have to be monitor waits (see code below).
MONITOR DUMP BEGIN
MONITOR java.lang.ref.ReferenceQueue$Lock(24ae5178) unowned
waiting to be notified: thread 2
MONITOR java.lang.ref.Reference$Lock(24ae5648) unowned
waiting to be notified: thread 1
MONITOR DUMP END
MONITOR TIME BEGIN (total = 0 ms) Tue Mar 30 10:06:58 2004
MONITOR TIME END
OS is Windows 2000 Pro.
VM's used are Suns 1.4.1_01-b01 and 1.4.2_02-b03.
Switches used are "-Xrunhprof:monitor=y,depth=50" with different combinations of "thread=y|n", "cpu=times|samples" as well as "-Xint", "-Xcheck:jni", "-Xss1m" and "-Xmx256m".
Oh, and btw, if I use "cpu=samples" the VM crashes after about several hundred lines are printed to the console.
On exit I see something like this:
HPROF ERROR: thread local table NULL in method exit 0093D9F8
HPROF ERROR: thread local table NULL in method exit 0093D9F8
HPROF ERROR: class ID already in use
HPROF ERROR : stack underflow in method exit
HPROF ERROR : stack underflow in method exit
HPROF ERROR : stack underflow in method exit
Dumping contended monitor usage ... CPU usage by timing methods ... done.
Any ideas what's happening here? Thanks!
robert
Now here's the code if anyone is interested:
package threads;
public class ThreadLockProfileTest implements Runnable {
// class level
private static final Object[] LOCKS = {"Lock1", "Lock2"};
public static void main( String[] args ) throws InterruptedException {
Thread[] threads = new Thread[30];
// create
System.out.println( "Creating" );
for ( int i = 0; i < threads.length; ++i ) {
ThreadLockProfileTest t = new ThreadLockProfileTest( LOCKS[i % LOCKS.length], "T" + i, 10 );
threads[i] = new Thread( t );
}
// start
System.out.println( "Starting" );
for ( int i = 0; i < threads.length; ++i ) {
threads.start();
}
// wait for exit
System.out.println( "Waiting" );
for ( int i = 0; i < threads.length; ++i ) {
try {
threads[i].join();
}
catch ( InterruptedException e ) {
System.err.println( "Interrupted during wait for " + threads[i] );
}
}
// done
System.out.println( "Exiting" );
}
// instance level
private final Object lock;
private String label;
private int number;
ThreadLockProfileTest( Object lock, String label, int number ) {
this.lock = lock;
this.label = label;
this.number = number;
}
public void run() {
message( "Started" );
for ( int i = 0; i < number; ++i ) {
test();
}
message( "Finished" );
}
private void test() {
message( "Entering" );
synchronized ( lock ) {
message( "Entered" );
// spend some time here
StringBuffer sb = new StringBuffer();
for ( int i = 0; i < 10000; ++i ) {
sb.append( "x" );
}
message( "About to leave (" + sb.length() + ")" );
}
message( "Leaving" );
}
private void message( String msg ) {
System.out.println( label + ":" + lock + ":" + msg );
}
}