[心缘地方]同学录
首页 | 功能说明 | 站长通知 | 最近更新 | 编码查看转换 | 代码下载 | 常见问题及讨论 | 《深入解析ASP核心技术》 | 王小鸭自动发工资条VBA版
登录系统:用户名: 密码: 如果要讨论问题,请先注册。

[备忘]WebappClassLoaderBase.loadClass时锁住BLOCK

上一篇:[备忘]Bootstrap switch 切换选中状态
下一篇:[GDS]Sabre查询

添加日期:2019-8-22 16:38:54 快速返回   返回列表 阅读100次
大量线程是BLOCK状态,WebappClassLoaderBase.loadClass时锁住了。
这个之前多次看到过,一直没当回事,心想loadClass怎么会锁呢?以为是其他问题引起的。

tomcat版本是7.0.79.0


"catalina-exec-499" #1617 daemon prio=5 os_prio=0 tid=0x00007f31ec221800 nid=0x31be waiting for monitor entry [0x00007f3125573000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1769)
        - waiting to lock <0x00000006c0006b20> (a org.apache.catalina.loader.WebappClassLoader)
        at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1735)
        at org.springframework.util.ClassUtils.isVisible(ClassUtils.java:1221)
        at org.springframework.util.ClassUtils.getAllInterfacesForClassAsSet(ClassUtils.java:1149)
        at org.springframework.util.ClassUtils.getAllInterfacesForClassAsSet(ClassUtils.java:1156)
        at org.springframework.util.ClassUtils.getAllInterfacesForClass(ClassUtils.java:1112)
        at org.springframework.data.redis.core.RedisTemplate.createRedisConnectionProxy(RedisTemplate.java:330)
        at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:206)



搜了下,有以下结果:
---------------
Tomcat有个Loader的设置,不指定,默认是org.apache.catalina.loader.WebappClassLoader. 
它不是并发的,load类时,貌似是给ClassLoader上锁,所有线程排队进行。

Tomcat重启时,Nginx会瞬间放进来几百上千个连接,蜂拥而至,同时loadClass,然后BLOCK住,
处理能力下降,但后续连接不断,最终就是一个死翘翘的状态。
-----------------
想并发的话,使用org.apache.catalina.loader.ParallelWebappClassLoader即可。

tomcat的conf/下有个context.xml,在<Context>下增加
<Loader loaderClass="org.apache.catalina.loader.ParallelWebappClassLoader" />
即可。

这个貌似是把锁放在了每个className上,锁级别降低了,并发性能就好一些。
----------------------
搜到一个大神的文章:
http://jm.taobao.org/2016/01/29/3721/
【并行类加载功能已经在捐献给Apache tomcat社区,并且被社区接受,在最新的Apache tomcat 7.0.65版本中已经包含该项功能。】

原来是大神搞的呀~7.0.65版本就可以了。
-------------------------
如何验证:
随便写个方法,把classLoader打印出来即可


@RequestMapping(value = "/welcome", method = RequestMethod.GET)
    public String welcom(HttpServletRequest req) {
        
        String classLoader = WelcomeController.class.getClassLoader().toString();
        req.setAttribute("classLoader", classLoader);
        
        return "index/welcome";
    }

 

评论 COMMENTS
没有评论 No Comments.

添加评论 Add new comment.
昵称 Name:
评论内容 Comment:
验证码(不区分大小写)
Validation Code:
(not case sensitive)
看不清?点这里换一张!(Change it here!)
 
评论由管理员查看后才能显示。the comment will be showed after it is checked by admin.
CopyRight © 心缘地方 2005-2999. All Rights Reserved