Home >Java >javaTutorial >How Java virtual machine implements deadlock
So far, I think the most effective tool for analyzing Java code problems is still java thread dump. The reasons are:
1. It can be used under any operating system platform.
2. In most cases, it can be used in a production environment.
3. Compared with the tools provided by the operating system, the information given by java thread dump is straightforward and directly corresponds to the application code.
4. It has little interference with the system being analyzed, so it can reflect real problems. Many other profiling or instrument tools themselves have great interference with JVM operation, often fail to expose real problems, and such tools cannot be used in production systems.
I think it is much easier to analyze Java virtual machine deadlocks than memory leaks under normal circumstances. Because when a deadlock occurs, the JVM is usually in a suspended state (hang), and thread dump can give static and stable information. To find a deadlock, you only need to find the thread in question. The problem of memory leaks is difficult to define. There are countless objects in a running JVM. Only those who write programs know which objects are garbage and which are not. Moreover, the reference relationships of objects are very complicated, making it difficult to get a clear definition. Object reference graph.
When a Java virtual machine deadlock occurs, observe from the operating system that the CPU usage of the virtual machine is zero and will soon disappear from the output of top or prstat. At this time, you can collect thread dump. Under Unix/Linux, kill -3
After getting the java thread dump, all you have to do is to find the thread "waiting for monitor entry". If a large number of threads are waiting to be locked at the same address (because for Java, there is only one thread for an object) lock), this indicates that a deadlock is likely to occur. For example:
"service-j2ee" prio=5 tid=0x024f1c28 nid=0x125 waiting for monitor entry [62a3e000..62a3f690] [27/Jun/2006:10:03:08] WARNING (26140): CORE3283: stderr: at com.sun.enterprise.resource.IASNonSharedResourcePool.internalGetResource(IASNonS haredResourcePool.java:625) [27/Jun/2006:10:03:08] WARNING (26140): CORE3283: stderr: - waiting to lock <0x965d8110> (a com.sun.enterprise.resource.IASNonSharedResourcePool) [27/Jun/2006:10:03:08] WARNING (26140): CORE3283: stderr: at com.sun.enterprise.resource.IASNonSharedResourcePool.getResource(IASNonSharedRes ourcePool.java:520) ................
In order to determine the problem, it is often necessary to collect a thread dump again after two minutes. If the output obtained is the same and there are still a large number of threads waiting to lock the same address, then It must be deadlocked.
How to find the thread currently holding the lock is the key to solving the problem. The method is to search the thread dump, look for "locked <0x965d8110>", and find the thread holding the lock.
[27/Jun/2006:10:03:08] WARNING (26140): CORE3283: stderr: "Thread-20" daemon prio=5 tid=0x01394f18 nid=0x109 runnable [6716f000..6716fc28] [27/Jun/2006:10:03:08] WARNING (26140): CORE3283: stderr: at java.net.SocketInputStream.socketRead0(Native Method) [27/Jun/2006:10:03:08] WARNING (26140): CORE3283: stderr: at java.net.SocketInputStream.read(SocketInputStream.java:129) [27/Jun/2006:10:03:08] WARNING (26140): CORE3283: stderr: at oracle.net.ns.Packet.receive(Unknown Source) [27/Jun/2006:10:03:08] WARNING (26140): CORE3283: stderr: at oracle.net.ns.DataPacket.receive(Unknown Source) [27/Jun/2006:10:03:08] WARNING (26140): CORE3283: stderr: at oracle.net.ns.NetInputStream.getNextPacket(Unknown Source) [27/Jun/2006:10:03:08] WARNING (26140): CORE3283: stderr: at oracle.net.ns.NetInputStream.read(Unknown Source) [27/Jun/2006:10:03:08] WARNING (26140): CORE3283: stderr: at oracle.net.ns.NetInputStream.read(Unknown Source) [27/Jun/2006:10:03:08] WARNING (26140): CORE3283: stderr: at oracle.net.ns.NetInputStream.read(Unknown Source) [27/Jun/2006:10:03:08] WARNING (26140): CORE3283: stderr: at oracle.jdbc.ttc7.MAREngine.unmarshalUB1(MAREngine.java:929) [27/Jun/2006:10:03:08] WARNING (26140): CORE3283: stderr: at oracle.jdbc.ttc7.MAREngine.unmarshalSB1(MAREngine.java:893) [27/Jun/2006:10:03:08] WARNING (26140): CORE3283: stderr: at oracle.jdbc.ttc7.Ocommoncall.receive(Ocommoncall.java:106) [27/Jun/2006:10:03:08] WARNING (26140): CORE3283: stderr: at oracle.jdbc.ttc7.TTC7Protocol.logoff(TTC7Protocol.java:396) [27/Jun/2006:10:03:08] WARNING (26140): CORE3283: stderr: - locked <0x954f47a0> (a oracle.jdbc.ttc7.TTC7Protocol) [27/Jun/2006:10:03:08] WARNING (26140): CORE3283: stderr: at oracle.jdbc.driver.OracleConnection.close(OracleConnection.java:1518) [27/Jun/2006:10:03:08] WARNING (26140): CORE3283: stderr: - locked <0x954f4520> (a oracle.jdbc.driver.OracleConnection) [27/Jun/2006:10:03:08] WARNING (26140): CORE3283: stderr: at com.sun.enterprise.resource.JdbcUrlAllocator.destroyResource(JdbcUrlAllocator.java:122) [27/Jun/2006:10:03:08] WARNING (26140): CORE3283: stderr: at com.sun.enterprise.resource.IASNonSharedResourcePool.destroyResource(IASNonSharedResourcePool.java:8 72) [27/Jun/2006:10:03:08] WARNING (26140): CORE3283: stderr: at com.sun.enterprise.resource.IASNonSharedResourcePool.resizePool(IASNonSharedResourcePool.java:1086) [27/Jun/2006:10:03:08] WARNING (26140): CORE3283: stderr: - locked <0x965d8110> (a com.sun.enterprise.resource.IASNonSharedResourcePool) [27/Jun/2006:10:03:08] WARNING (26140): CORE3283: stderr: at com.sun.enterprise.resource.IASNonSharedResourcePool$Resizer.run(IASNonSharedResourcePool.java:1178) [27/Jun/2006:10:03:08] WARNING (26140): CORE3283: stderr: at java.util.TimerThread.mainLoop(Timer.java:432) [27/Jun/2006:10:03:08] WARNING (26140): CORE3283: stderr: at java.util.TimerThread.run(Timer.java:382)
In this example, the thread holding the lock is waiting for Oracle to return the result, but cannot wait for the response, so a deadlock occurs.
If the thread holding the lock is still waiting to lock another object, then follow the above method until you find the source of the deadlock.
In addition, such threads are often seen in thread dumps. They are threads that wait for a condition and actively give up the lock.
For example:
"Thread-1" daemon prio=5 tid=0x014e97a8 nid=0x80 in Object.wait() [68c6f000..68c6fc28] at java.lang.Object.wait(Native Method) - waiting on <0x95b07178> (a java.util.LinkedList) at com.iplanet.ias.util.collection.BlockingQueue.remove(BlockingQueue.java:258) - locked <0x95b07178> (a java.util.LinkedList) at com.iplanet.ias.util.threadpool.FastThreadPool$ThreadPoolThread.run(FastThreadPool.java:241) at java.lang.Thread.run(Thread.java:534)
Sometimes it is necessary to analyze this type of thread, especially the conditions for thread waiting.
In fact, Java thread dump is not only used to analyze deadlocks. Other weird behaviors when running Java applications can be analyzed with thread dump.
***, in Java SE 5, the jstack tool is added, and thread dump can also be obtained. In Java SE 6, you can also easily find deadlocks involving object monitors and java.util.concurrent.locks through the graphical tool of jconsole.
The above is the detailed content of How Java virtual machine implements deadlock. For more information, please follow other related articles on the PHP Chinese website!