搜索
首页Javajava教程Java虚拟机如何实现死锁

到目前为止,我认为分析Java代码问题的最有效的工具仍然是java thread dump,原因是:

1.任何操作系统平台下都可以使用。

2.在多数情况下,可以在生产环境中使用。

3.和操作系统提供的工具相比,java thread dump给出的信息是直白的,直接对应到应用代码。

4.它对被分析的系统干扰很小,因此能反应真实的问题。而其它很多profiling或Instrument工具本身对JVM运行有很大的干扰,经常不能暴露出真正的问题,而且这种工具不能用于生产系统。


我觉得在通常情况下分析Java虚拟机死锁比分析内存泄漏要容易的多。因为死锁发生时,JVM通常处于挂起状态(hang住了),thread dump可以给出静态稳定的信息,查找死锁只需要查找有问题的线程。而内存泄漏的问题却很难界定,一个运行的JVM里有无数对象存在,只有写程序的人才知道哪些对象是垃圾,而哪些不是,而且对象的引用关系非常复杂,很难得到一份清晰的对象引用图。

Java虚拟机死锁发生时,从操作系统上观察,虚拟机的CPU占用率为零,很快会从top或prstat的输出中消失。这时你就可以收集thread dump了,Unix/Linux 下是kill -3 ,在Windows下可以在JVM的console窗口上敲Ctrl-Break。根据不同的设置,thread dump会输出到当前控制台上或应用服务器的日志里。

拿到java thread dump后,你要做的就是查找"waiting for monitor entry"的thread,如果大量thread都在等待给同一个地址上锁(因为对于Java,一个对象只有一把锁),这说明很可能死锁发生了。比如:

"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)  ................


为了确定问题,常常需要在隔两分钟后再次收集一次thread dump,如果得到的输出相同,仍然是大量thread都在等待给同一个地址上锁,那么肯定是死锁了。

如何找到当前持有锁的线程是解决问题的关键。方法是搜索thread dump,查找"locked <0x965d8110>", 找到持有锁的线程。

[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)


在这个例子里,持有锁的线程在等待Oracle返回结果,却始终等不到响应,因此发生了死锁。

如果持有锁的线程还在等待给另一个对象上锁,那么还是按上面的办法顺藤摸瓜,直到找到死锁的根源为止。

另外,在thread dump里还会经常看到这样的线程,它们是等待一个条件而主动放弃锁的线程。
例如:

"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)


有时也会需要分析这类线程,尤其是线程等待的条件。

其实,Java thread dump并不只用于分析死锁,其它Java应用运行时古怪的行为都可以用thread dump来分析。

***,在Java SE 5里,增加了jstack的工具,也可以获取thread dump。在Java SE 6里, 通过jconsole的图形化工具也可以方便地查找涉及object monitors 和java.util.concurrent.locks死锁。

以上是Java虚拟机如何实现死锁的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文转载于:亿速云。如有侵权,请联系admin@php.cn删除
Java中'类::实例方法”方法引用如何正确理解和应用?Java中'类::实例方法”方法引用如何正确理解和应用?Apr 19, 2025 pm 03:39 PM

Java方法引用“类::实例方法”的疑惑解答在Java编程中,方法引用是一种简洁而强大的功能,它允许开发者通过�...

Spring Boot异步任务中,子线程如何访问主线程的Request信息?Spring Boot异步任务中,子线程如何访问主线程的Request信息?Apr 19, 2025 pm 03:36 PM

SpringBoot项目中子线程无法访问主线程Request信息的问题及解决方案在Spring...

如何在Java中动态配置实体类注解参数以适应不同环境?如何在Java中动态配置实体类注解参数以适应不同环境?Apr 19, 2025 pm 03:33 PM

如何在Java中动态配置实体类注解参数在开发过程中,常常会遇到需要根据不同环境动态配置参数的问题。特别�...

如何确保Spring Retry的@Retryable注解中自定义监听器仅在指定时被调用?如何确保Spring Retry的@Retryable注解中自定义监听器仅在指定时被调用?Apr 19, 2025 pm 03:30 PM

使用SpringRetry的@Retryable注解时如何正确指定自定义监听器在使用Spring...

如何在SpringBoot中使用@RequestBody注解正确接收非JSON格式的字符串参数?如何在SpringBoot中使用@RequestBody注解正确接收非JSON格式的字符串参数?Apr 19, 2025 pm 03:27 PM

在SpringBoot中使用@RequestBody注解接收非JSON格式的字符串参数在SpringBoot开发中,我们经常使用@RequestBody注解来处理...

如何优化热点数据的筛选以提高数据同步效率?如何优化热点数据的筛选以提高数据同步效率?Apr 19, 2025 pm 03:24 PM

热点数据筛选优化策略的探讨在处理数据同步时,如何有效地筛选热点数据是一个关键问题。我们的场景是:上...

Nacos注册中心下,OpenFeign如何实现跨命名空间服务调用?Nacos注册中心下,OpenFeign如何实现跨命名空间服务调用?Apr 19, 2025 pm 03:21 PM

Nacos注册中心与OpenFeign跨命名空间服务调用本文探讨在使用Nacos作为注册中心的情况下,OpenFeign能否实现不同命�...

在使用Netty4开发WebSocket服务器时,如何确保浏览器正确识别401响应?在使用Netty4开发WebSocket服务器时,如何确保浏览器正确识别401响应?Apr 19, 2025 pm 03:18 PM

使用Netty4开发WebSocket服务器时,如何让浏览器正确识别401响应?在使用Netty开发WebSocket服务器时,经常会遇到需�...

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热工具

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )专业的PHP集成开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

EditPlus 中文破解版

EditPlus 中文破解版

体积小,语法高亮,不支持代码提示功能

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中