记录一次定位死锁的问题

近期,别的团队在使用SPC1 (Storage performance council,一个性能测试机构)

The SPC is a non-profit corporation founded to define, standardize and promote storage system benchmarks and to disseminate objective, verifiable performance data to the computer industry and its customers. SPC membership is open to all companies, academic institutions and individuals

百度翻译:SPC是一个成立非营利公司的定义,规范和促进存储系统基准和传播目的,可验证的性能数据,计算机行业和客户。SPC的会员资格是开放给所有企业,学术机构和个人

 

做性能测试时,发现在有的主机上(1个主机上同时运行多jvm实例)时,有部分jvm实例

运行时的IOPS为0的情况.

然后通过jstack到处的线程信息,发现有检测到死锁.

最终反编译了SPC1的源代码,发现问题在于代码中多次使用到复杂的synchronized 块,但是实现的代码效果就是一个有界缓冲池BoundedBuffer.(没办法贴出代码了 虽说是个org但是是要收费才能成为member的)

估计当时还没有ArrayBlockingQueue这个东西,所以才会自己去实现的.

这个问题主要给我的一些经验就是如何定位死锁问题:

1.对于这种各个类交错的同步块,可以试着写出同步代码的执行路径.

    比如在获取A后接着获取B的锁这样的,考虑比较容易出现死锁的分支.(主要还是结合内存堆栈和线程转储文件来看.),一般在线程转储的文件中都带有,获取的类对象和 等待获取的类对象,一般都在这附近.你可以尝试着使用ECLIPSE MAT 来查看这个对象的状态到底是咋样的.

2.尽量缩小锁的范围,或者同步块的范围.尽量减少持有A时,同时去请求B的情况.

由于具体的代码没有办法贴出来,所以,只能说下当时的解决思路:

我的解决思路:

[1]开放调用:如果在调用某个方法时,不需要持有锁,那么这种调用就是开放调用./open call

具体可以参考:<Java并发编程实践  Java concurrency in practice.> 10.1.4节开放调用.

由于对业务代码不熟,所以只能单独解决死锁问题,当时是根据[1]中所说,缩小代码块,修改为开放调用.最后长时间运行没有再出现死锁问题.


最后.反馈给SPC 协会的成员,他们没有使用我提供的补丁,而是将自己实现的BoundedBuffer,替换为了ArrayBlockingQueue.

o(╯□╰)o

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值