Ticket #115 (closed Bug: fixed)
应用重启与el表达式的关系
| Reported by: | chenchongqi | Owned by: | |
|---|---|---|---|
| Priority: | major | Milestone: | |
| Component: | 报价库 | Version: | 报价库5.0 |
| Keywords: | el表达式,重启 | Cc: | |
| Due Date: |
Description (last modified by chenchongqi) (diff)
从3月份开始,报价前台应用重启次数频繁,从日志中看当时负载并不高:
system stat: top - 06:07:16 up 77 days, 8:48, 0 users, load average: 1.49, 2.05, 1.68 Tasks: 118 total, 1 running, 116 sleeping, 1 stopped, 0 zombie Cpu(s): 10.5% us, 1.3% sy, 0.0% ni, 81.7% id, 4.8% wa, 0.2% hi, 1.5% si Mem: 10237872k total, 10176508k used, 61364k free, 105708k buffers Swap: 2096472k total, 208k used, 2096264k free, 3955388k cached
在jvm.log里我们发现大量的locked状态线程:
http-app-a-8081-918$845068310" daemon prio=10 tid=0x0000002b4da53400 nid=0x4d38 waiting for monitor entry [0x00000
00040f3c000..0x0000000040f3dbb0]
java.lang.Thread.State: BLOCKED (on object monitor)
at javax.el.BeanELResolver.getProps(BeanELResolver.java:308)
- waiting to lock <0x0000002aa9948cc0> (a java.util.WeakHashMap)
at javax.el.BeanELResolver.getValue(BeanELResolver.java:178)
at com.caucho.jsp.el.PageContextELResolver.getValue(PageContextELResolver.java:175)
at com.caucho.el.ArrayResolverExpr.getValue(ArrayResolverExpr.java:148)
at com.caucho.el.PathExpr.getValue(PathExpr.java:142)
at com.caucho.el.EqExpr.evalBoolean(EqExpr.java:78)
at com.caucho.el.ConditionalExpr.evalString(ConditionalExpr.java:133)
at _jsp._price__jsp._jspService(_price__jsp.java:1075)
为什么el表达式这里会有WeakHashMap的lock现象呢,我们从el表达式的源码和文档可以看到,每个el表达式的变量是有不同的作用域的,如果不指定作用域,取值的时候会分别去page、request、session、application里面去取,直到取到为止,删除变量的时候,也是会全部作用域都去删一遍,可见没有指定作用域的el表达式会有线程间的锁竞争。
而报价库列表页里面的el表达式太多了,这里必须要尽快去优化。同样大家以后用到el表达式的地方必须指定作用域,而且也不要滥用。
2013-3-25分割线
近期el表达式导致锁阻塞的情况比较严重,经跟踪大部分跟索引页频繁使用的tag:priceStaticPath相关,该tag用于生成url,一个页面使用几百次,并且发现tag范围内使用的el变量尽管声称了pagescope,但是都会参与锁竞争,具体原因 估计是因为doTag()方法是额外占用一条resin线程来处理,因此变量转为线程间共享,el的page作用域声明失效 ,经过处理把使用这个tag的地方改成函数,上线观察后el表达式的锁大大减少。
Attachments
Change History
comment:2 Changed 14 years ago by yuanhuoqing
已对报价索引页的各个循环和el定义的变量加了指定作用域的处理,并已更新到线上,目前观察重启的日志还是会出现 java.lang.Thread.State: BLOCKED (on object monitor)
at javax.el.BeanELResolver.getProps(BeanELResolver.java:308)
- waiting to lock <0x0000002aa9948cc0> (a java.util.WeakHashMap?) at javax.el.BeanELResolver.getValue(BeanELResolver.java:178)
![(please configure the [header_logo] section in trac.ini)](http://www1.pconline.com.cn/hr/2009/global/images/logo.gif)
