📄 stack.html
字号:
You can also find out if the stack trace came from a Windows 95, an NT,
or UNIX machine by looking for any waiting threads. On a UNIX machine the
waiting threads are named explicitly. On a Windows 95, or NT machine only
a count of the waiting threads is displayed:
<UL>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif"><STRONG>Windows 95/NT:</STRONG> Finalize me queue lock:
<unowned> Writer: 1</FONT>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif"><STRONG>UNIX:</STRONG> Finalize me queue lock: <unowned><BR>
waiting to be notified "Finalizer Thread"</FONT>
</UL>
<A NAME="package"></A>
<H3>Which Thread Package was Used?</H3>
Windows 95 and Windows NT Java VMs are by default native
thread Java VMs. UNIX Java VMs are by default green thread Java
VMs, they use a pseudo
thread implementation. To make your Java VM use native threads you
need to supply the <CODE>-native</CODE> parameter, for example,
<CODE>java -native MyClass</CODE>.
<P>
By verifying the existence of an <CODE>Alarm monitor</CODE> in the stack
trace output you can identify that this stack trace came from a green
threads Java VM.
<A NAME="states"></A>
<H3>What are the Thread States?</H3>
You will see many different threads in many different states in a snapshot
from a Java VM stack trace. This table describes the various keys
and their meanings.
<P>
<TABLE BORDER=1>
<TR>
<TH><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Key</FONT></TH><TH><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Meaning</FONT></TH></TR>
<TR>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">R</FONT></TD>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Running or runnable thread</FONT></TD>
</TR>
<TR>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">S</FONT></TD>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Suspended thread</FONT></TD>
</TR>
<TR>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">CW</FONT></TD>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Thread waiting on a condition variable</FONT></TD>
</TR>
<TR>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">MW</FONT></TD>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Thread waiting on a monitor lock</FONT></TD>
</TR>
<TR>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">MS</FONT></TD>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Thread suspended waiting on a monitor lock</FONT></TD>
</TR>
</TABLE>
<p>
Normally, only threads in <CODE>R</CODE>, <CODE>S</CODE>,
<CODE>CW</CODE> or <CODE>MW</CODE> should appear in the
stack trace. If you see a thread in state <CODE>MS</CODE>, report
it to Sun Microsystems, through the Java Developer
Connection<FONT SIZE="-2"><SUP>SM</SUP></FONT> (JDC) Bug Parade feature,
because there is a good chance it is a bug. The reason being that most of the
time a thread in <CODE>Monitor Wait (MW)</CODE> state will appear in the
<CODE>S</CODE> state when it is suspended.
<P>
Monitors are used to manage access to code that should only be run
by a single thread at a time. Monitors are covered in more detail in the next section. The other two common thread states you may see are R, runnable threads
and CW, threads in a condition wait state. Runnable threads by definition
are threads that could be running or are running at that instance of time. On a multi-processor machine running a true multi-processing Operating System it is possible for all the runnable threads to be running at one time. However its
more likely for the other runnable threads to be waiting on the thread
scheduler to have their turn to run.
<p>
Threads in a condition wait state can be thought of as waiting for an event
to occur. Often a thread will appear in state CW if it is in a <CODE>Thread.sleep</CODE> or in a synchronized wait. In our earlier stack trace our main
method was waiting for a thread to complete and to be nofified of its
completion. In the stack trace this appears as
</FONT>
<PRE>
"main" (TID:0xebc981e0, sys_thread_t:0x26bb0,
state:CW) prio=5
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:424)
at HangingProgram.main(HangingProgram.java:33)
</PRE>
<FONT FACE="Verdana, Arial, Helvetica, sans-serif">
The code that created this stack trace is as follows:
</FONT>
<PRE>
synchronized(t1) {
try {
t1.wait(); //line 33
}catch (InterruptedException e){}
}
</PRE>
<FONT FACE="Verdana, Arial, Helvetica, sans-serif">
In the Java 2 release monitor operations, including our wait here, are handled by the Java Virtual Machine through a JNI call to sysMonitor. The condition
wait thread is kept on a special monitor wait queue on the object it is waiting
on. This explains why even though you are only waiting on an object that the
code still needs to be synchronized on that object as it is infact using
the monitor for that object.
<A NAME="monitors"></A>
<H3>Examining Monitors</H3>
This brings us to the other part of the stack trace: the monitor dump.
If you consider that the threads section of a stack trace identifies the
multithreaded part of your application, then the monitors section
represents the parts of your application that are single threaded.
<P>
It may be easier to imagine a monitor as a car wash. In most car washes, only
one car can be in the wash at a time. In your Java code only one thread
at a time can have the lock to a synchronized piece of code.
All the other threads queue up to enter the synchronized code just
as cars queue up to enter the car wash.
<P>
A monitor can be thought of as a lock on an object, and every object
has a monitor. When you generate a stack trace, monitors are either
listed as being registered or not. In the majority of cases these
registered monitors, or system monitors, should not be the cause of
your software problems, but it helps to be able to understand and recognize
them. The following table describes the common registered monitors:
<P>
<TABLE BORDER=1>
<TR>
<TH><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Monitor</FONT></TH><TH><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Description</FONT></TH></TR>
<TR>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">utf8 hash table</FONT></TD>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Locks the hashtable of defined
<BR>i18N Strings that were loaded from the class constant pool.</FONT></TD>
</TR>
<TR>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">JNI pinning lock</FONT></TD>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Protects block copies of arrays to native method code.</FONT></TD>
</TR>
<TR>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">JNI global reference lock</FONT></TD>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Locks the global reference table which holds values that need to be
explicitly freed, and will outlive the lifetime of the native method call.</FONT></TD>
</TR>
<TR>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">BinClass lock</FONT></TD>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Locks access to the loaded and resolved classes list. The global table list of classes</FONT></TD>
</TR>
<TR>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Class linking lock</FONT></TD>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Protects a classes data when loading native libraries to resolve symbolic references</FONT></TD>
</TR>
<TR>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">System class loader lock</FONT></TD>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Ensures that only one thread is loading a system class at a time.</FONT></TD>
</TR>
<TR>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Code rewrite lock</FONT></TD>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Protects code when an optimization is attempted.</FONT></TD>
</TR>
<TR>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Heap lock</FONT></TD>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Protects the Java heap during heap memory management</FONT></TD>
</TR>
<TR>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Monitor cache lock</FONT></TD>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Only one thread can have access to the monitor cache at a time this lock ensures the integrity of the monitor cache</FONT></TD>
</TR>
<TR>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Dynamic loading lock</FONT></TD>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Protects Unix green threads JVMs from loading the shared library stub libdl.so more than once at a time.</FONT></TD>
</TR>
<TR>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Monitor IO lock</FONT></TD>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Protects physical I/O for example,
<BR>open and read.</FONT></TD>
</TR>
<TR>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">User signal monitor</FONT></TD>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Controls access to the signal handler if a user signal USRSIG in green threads JVMs.</FONT></TD>
</TR>
<TR>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Child death monitor</FONT></TD>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Controls access to the process wait information when using the runtime system calls to run locals commands in a green threads JVM.</FONT></TD>
</TR>
<TR>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">I/O Monitor</FONT></TD>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Controls access to the threads file descriptors for poll/select events</FONT></TD>
</TR>
<TR>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Alarm Monitor</FONT></TD>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Controls access to a clock handler used in green threads JVMs to handle timeouts</FONT></TD>
</TR>
<TR>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Thread queue lock</FONT></TD>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Protects the queue of active threads</FONT></TD>
</TR>
<TR>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Monitor registry</FONT></TD>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Only one thread can have access to the monitor registry at a time this lock ensures the integrity of that registry</FONT></TD>
</TR>
<TR>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Has finalization queue lock *</FONT></TD>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Protects the list of queue lock objects that have been garbage-collected,
and deemed to need finalization. They are copied to the Finalize me queue</FONT></TD>
</TR>
<TR>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Finalize me queue lock *</FONT></TD>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Protects a list of objects that can be finalized at leisure</FONT></TD>
</TR>
<TR>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Name and type hash table lock *</FONT></TD>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Protects the JVM hash tables of constants and their types</FONT></TD>
</TR>
<TR>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">String intern lock *</FONT></TD>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Locks the hashtable of defined
<BR>Strings that were loaded from the class constant pool</FONT></TD>
</TR>
<TR>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Class loading lock *</FONT></TD>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Ensures only one thread loads a class at a time</FONT></TD>
</TR>
<TR>
<TR>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Java stack lock *</FONT></TD>
<TD><FONT FACE="Verdana, Arial, Helvetica, sans-serif">Protects the free stack segments list</FONT></TD>
</TR>
</TABLE>
<BLOCKQUOTE>
<HR>
<STRONG>Note:</STRONG>
* Lock only appeared in pre-Java 2 stack traces
<HR>
</BLOCKQUOTE>
<P>
The monitor registry itself is protected by a monitor. This
means the thread that owns the lock is the last thread to use a
monitor. It is very likely this thread is also the current
thread.
Because only one thread can enter a synchronized block at a time, other
threads queue up at the start of the synchronized code and appear as
thread state <CODE>MW</CODE>. In the monitor cache dump, they are denoted
as "waiting to enter" threads. In user code a monitor is called into action
wherever a synchronized block or method is used.
<P>
Any code waiting on an object or event (a wait method) also
has to be inside a synchronized block. However, once the wait method is called,
the lock on the synchronized object is given up.
<P>
When the thread in the wait state is notified of an event to the object,
it has to compete for exclusive access to that object, and it has to
obtain the monitor. Even when a thread has sent a "notify event"
to the waiting threads, none of the waiting threads can actually gain
control of the monitor lock until the notifying thread has left its
synchronized code block.
<P>
You will see "Waiting to be notified" for threads at the wait method
<A NAME="practice"></A>
<H3>Putting the Steps Into Practice</H3>
<b>Example 1</b>
<p>
Consider a real-life problem such as Bug ID
<A HREF="/developer/bugParade/bugs/4098756.html">4098756</A>, for example.
You can find details on this bug in JDC Bug Parade.
This bug documents a problem that occurs when using a <CODE>Choice</CODE>
Component on Windows 95.
<P>
When the user selects one of the choices from the <CODE>Choice</CODE> Component
using the mouse, everything is fine. However, when the user tries to use
an Arrow key to move up or down the list of choices, the Java application
freezes.
<P>
Fortunately, this problem is reproducible and there was a Java stack
trace to help track down the problem.
The full stack trace is in the bug report page, but you only need
to focus on the following two key threads:
</FONT>
<PRE>
<FONT SIZE="-1">
"AWT-Windows" (TID:0xf54b70,
sys_thread_t:0x875a80,Win32ID:0x67,
state:MW) prio=5
java.awt.Choice.select(Choice.java:293)
sun.awt.windows.WChoicePeer.handleAction(
WChoicePeer.java:86)
"AWT-EventQueue-0" (TID:0xf54a98,sys_thread_t:0x875c20,
Win32ID:0x8f, state:R) prio=5
java.awt.Choice.remove(Choice.java:228)
java.awt.Choice.removeAll(Choice.java:246)
</FONT>
</PRE>
<FONT FACE="Verdana, Arial, Helvetica, sans-serif">
<P>
The <CODE>AWT-EventQueue-0</CODE> thread is in a runnable state inside the
<CODE>remove</CODE> method. <CODE>Remove</CODE> is synchronized, which
explains why the <CODE>AWT-Windows</CODE> thread cannot enter
the <CODE>select</CODE> method. The <CODE>AWT-Windows</CODE> thread is in
<CODE>MW</CODE> state (monitor wait); however, if you keep taking stack
traces, this situation does not change and the graphical user interface
(GUI) appears to have frozen.
<P>
This indicates that the <CODE>remove</CODE> call never returned. By following
the code path to the <CODE>ChoicePeer</CODE> class, you can see this is making
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -