`
roc08
  • 浏览: 224267 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

并发类加载引起的死锁

阅读更多
 
近来系统启动经常出现卡死现象,要启动几次才能起来,由于是OSGi环境,系统启动时会加载大量的类,并且由不同classloader加载,因此怀疑是类加载死锁,通过jconsole看到进程间相互等待的现象,通过dump 得到很多进程block的信息,分析找到问题位置
xxxxx.base.dao.Activator.registerPOJO在注册po时发生了死锁。由于使用OSGi时hibernate并不支持osgi环境,因此po的加载注册是平台自己写的。
定位到出现问题的位置后,下面来分析原因,
registerPOJO方法如下,



可以看到此方法是synchronized的,应该不会出现死锁,继续看方法中的parseBundleClasses方法



注意到此方法中存在synchronized静态变量,因此同时存在了类锁和对象锁,如果有一个线程拿到类锁,另外一个线程拿到对象锁,变出现了死锁,上网搜索发现阿里也出现过这个情况
http://alipaymiddleware.com/%E6%9C%8D%E5%8A%A1%E5%AE%B9%E5%99%A8/osgi%E7%B1%BB%E5%8A%A0%E8%BD%BD%E6%AD%BB%E9%94%81%E5%88%86%E6%9E%90/
文章中给出的解决方法稍后再说,我怀疑还有其他情况导致死锁,我们的po分布的不同的bundle中,但po中使用了枚举类型,而枚举会分布在其他bundle中,因此在加载本bundle的po时需要同时加载其枚举类型,这时会需要其他bundle的加载器进行加载,因此此线程出现阻塞,而其他bundle也需要其他bundle的加载器加载其需要的枚举类型,这样极有可能出现循环等待。
下面说一下解决方法,根据上面文章中提到的,解决的办法就是去掉锁和加锁,
去掉锁就是采用并发加载的方式,不同的线程就不会需要在去获取classloader的对象锁,也就不会有这个死锁的问题,同时并发加载的方式对于系统的性能是有提升的。加锁就是在加载自定义的类的时候也对当前的classloader对象进行加锁,这样可以保证不再出现死锁。
结合我们的实际代码,我觉得适合我们的
去掉锁
如果是jdk1.6可以升级到1.7或者在jvm中加入参数

dump信息

"SpringOsgiExtenderThread-74" prio=5 tid=104 BLOCKED
at java.lang.ClassLoader.checkCerts(ClassLoader.java:782)
at java.lang.ClassLoader.preDefineClass(ClassLoader.java:487)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:625)
at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.findClass(BundleWiringImpl.java:2279)
   Local Variable: byte[]#2006
   Local Variable: java.lang.String#71363
   Local Variable: java.lang.String#71364
at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1501)
   Local Variable: java.util.HashSet#5911
   Local Variable: java.lang.String#71365
at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:75)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1955)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at org.apache.felix.framework.Felix.loadBundleClass(Felix.java:1844)
at org.apache.felix.framework.BundleImpl.loadClass(BundleImpl.java:937)
at gboat2.base.dao.Activator.parseBundleClasses(Activator.java:314)
   Local Variable: org.apache.felix.framework.BundleImpl#35
   Local Variable: java.lang.String#70146
   Local Variable: java.lang.String#43279
   Local Variable: java.util.AbstractList$Itr#23
   Local Variable: java.lang.ClassNotFoundException#1
   Local Variable: java.util.ArrayList#12164
   Local Variable: java.util.AbstractList$Itr#22
   Local Variable: java.util.ArrayList#12163
   Local Variable: java.lang.String[]#2192
at gboat2.base.dao.Activator.registerPOJO(Activator.java:177)
at gboat2.base.dao.Activator.setApplicationContext(Activator.java:93)
   Local Variable: java.util.LinkedHashMap#15659
   Local Variable: java.util.LinkedHashMap#15601
at org.springframework.context.support.ApplicationContextAwareProcessor.invokeAwareInterfaces(ApplicationContextAwareProcessor.java:117)
at org.springframework.context.support.ApplicationContextAwareProcessor.postProcessBeforeInitialization(ApplicationContextAwareProcessor.java:92)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:396)
   Local Variable: org.springframework.context.support.ApplicationContextAwareProcessor#2
   Local Variable: java.util.AbstractList$Itr#24
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1475)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:521)
   Local Variable: class gboat2.base.dao.Activator
   Local Variable: org.springframework.beans.BeanWrapperImpl#3
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
   Local Variable: org.springframework.beans.factory.support.AbstractBeanFactory$1#3
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:626)
   Local Variable: java.util.ArrayList#11365
   Local Variable: java.util.AbstractList$Itr#14
   Local Variable: org.springframework.beans.factory.support.RootBeanDefinition#642
   Local Variable: java.lang.String#55756
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
   Local Variable: java.lang.String[]#1978
at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.access$1600(AbstractDelegatedExecutionApplicationContext.java:69)
at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext$4.run(AbstractDelegatedExecutionApplicationContext.java:355)
   Local Variable: org.springframework.beans.factory.support.DefaultListableBeanFactory#2
at org.springframework.osgi.util.internal.PrivilegedUtils.executeWithCustomTCCL(PrivilegedUtils.java:85)
   Local Variable: org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext$4#12
   Local Variable: org.springframework.osgi.util.BundleDelegatingClassLoader#8
at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.completeRefresh(AbstractDelegatedExecutionApplicationContext.java:320)
   Local Variable: org.springframework.osgi.context.support.OsgiBundleXmlApplicationContext#7
at org.springframework.osgi.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor$CompleteRefreshTask.run(DependencyWaiterApplicationContextExecutor.java:132)
   Local Variable: java.lang.Object#341
   Local Variable: org.springframework.osgi.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor$CompleteRefreshTask#12
at java.lang.Thread.run(Thread.java:662)

参考文档:
http://osdir.com/ml/dev-felix-apache/2009-04/msg00139.html
https://www.mail-archive.com/users@felix.apache.org/msg15209.html
https://bugs.eclipse.org/bugs/show_bug.cgi?id=121737
http://alipaymiddleware.com/%E6%9C%8D%E5%8A%A1%E5%AE%B9%E5%99%A8/osgi%E7%B1%BB%E5%8A%A0%E8%BD%BD%E6%AD%BB%E9%94%81%E5%88%86%E6%9E%90/
  • 大小: 75.5 KB
  • 大小: 58.4 KB
分享到:
评论

相关推荐

    并发访问ORACLE数据库的数据死锁分析和解决措施.pdf

    并发访问ORACLE数据库的数据死锁分析和解决措施.pdf

    操作系统-死锁

    从进程同步的概念可以知道,当并发进程需要竞争使用资源或需要相互协作向前推进时,如果不采取同步措施,或同步措施不恰当,则很容易导致并发进程不能向前推进而陷入僵局,即死锁现象。死锁是发生在一组相互竞争或...

    SQL Server作业失败引起死锁的故障排除.pdf

    SQL Server作业失败引起死锁的故障排除.pdf

    死锁典型例题,对理解死锁的计算类题目有帮助

    死锁典型例题,对理解死锁的计算类题目有帮助

    Oracle外键不加索引引起死锁示例

    主要介绍了Oracle外键不加索引引起死锁的情况及解决,需要的朋友可以参考下

    仿真模拟银行家算法对死锁的避免 C#

    设计5个并发进程共享3类不同的系统资源,即A类资源、B类资源、C类资源和可用资源数量A类资源、B类资源、C类资源。系统进行安全性检查,判断是否有安全系列。如果能够找到安全序列,系统将列出计算过程和安全序列的...

    银行家算法的思想,编写程序,解决并发进程的死锁问题。

    根据银行家算法的思想,编写程序,解决并发进程的死锁问题。 本实验要求设计并实现银行家算法。银行家算法是死锁避免的经典算法,其核心思想是:进程动态地申请资源,每次申请资源时系统都执行安全状态检查算法判断...

    并发性死锁和饥饿PPT教案学习.pptx

    并发性死锁和饥饿PPT教案学习.pptx

    解决了关闭死锁的CSerialPort类项目

    1.它解决了,串口关闭时出现死锁不响应问题,可以直接用到开发的项目上。 2.并且是扩展了的串口助手,具有通信协议编辑和使用功能, 3.软件升级检测,值得做软件升级例子使用。 4.最重要的是源代码很不错,很值得...

    SQL Server死锁总结

    SQL Server死锁总结 死锁的四个必要条件: 互斥条件(Mutual exclusion):资源不能被共享,只能由一个进程使用。 请求与保持条件(Hold and wait):已经得到资源的进程可以再次申请新的资源。 非剥夺条件(No pre-...

    java 类加载调试

    他们提供的见解有助亍理解和解决常见的 Java 异常,例如 NoClassDefFoundError 和 ClassNotFoundException,以及更有挅戓性的问题,例如类装入器约束迗反和死锁。在第 1 部分中,他们详细描述了 Java 类装入的工作...

    java死锁源码java死锁源码

    java死锁源码java死锁源码java死锁源码java死锁源码java死锁源码java死锁源码java死锁源码java死锁源码java死锁源码java死锁源码java死锁源码java死锁源码java死锁源码java死锁源码java死锁源码java死锁源码java死锁...

    基于Petri网的并发编程死锁预防策略 (2012年)

    针对并发编程中的死锁问题,提出了一种具有同步信号的并发程序的Petri网模型――S3PS(简单连续信号进程系统)网,这种Petri网子类保持活性的充分必要条件是它的虹吸非空.在此基础上,通过对严格极小虹吸加入控制弧...

    死锁查询sql语句

    oracle数据库死锁查询并处理,被锁对象、引起死锁原因等查询及解决方法

    死锁详解,如何表面死锁

    死锁详解,详细的为你讲解什么事死锁,如何克服死锁。

    深入浅出SQLServer中的死锁

    死锁的本质是一种僵持状态,是多个主体对于资源的争用而导致的。理解死锁首先需要对死锁所涉及的相关观念有一个理解。要理解SQLServer中的死锁,更好的方式是通过类比从更大的面理解死锁。比如说一个经典的例子就是...

    解决ORACLE死锁问题

    一、数据库死锁的现象 程序在执行的过程中,点击确定或保存按钮,程序没有响应,也没有出现报错。 二、死锁的原理 当对于数据库某个表的某一列做更新或删除等操作,执行完毕后该条语句不提 交,另一条对于这一列...

    死锁检测源代码

    死锁检测源代码

    postgresql查询死锁以及杀死死锁进程sql.txt

    查询sql的死锁进程,查找并杀死。解决生产数据库中卡死的现象。postgresql查询死锁以及杀死死锁进程sql

    oracle-死锁查询

    oracle死锁问题查询代码,仅供参考,有问题大家一起交流

Global site tag (gtag.js) - Google Analytics