Spring集成Shiro时内存溢出的问题分析

        前段时间有一天系统访问量突然增加,系统每隔一两个小时就会由于内存瞬时飙升而宕机。查看内存dump文件发现其中ShiroSimpleSession对象异常多。后来经分析才发现是由于使用Spring集成Shiro时配置不当导致的。当时的配置如下:

  1. "sessionManager" class="org.apache.shiro.session.mgt.DefaultSessionManager">  
  2.     "globalSessionTimeout" value="3600000"/>  
  3.     "deleteInvalidSessions" value="true"/>  
  4.     "sessionValidationSchedulerEnabled" value="true"/>  
  5.     "sessionDAO" ref="sessionDAO"/>  
  6.  

        该配置中使用Shiro自带的用户会话超时校验功能,每一个小时执行一次该逻辑。 

        经过研究源代码发现有需要进行认证授权等验证的请求进入的时候,DefaultSessionManager对象(即上面配置的"sessionManager"bean)会判断其中的sessionValidationScheduler属性对象是否存在(该对象负责执行会话超时校验逻辑)。如果不存在,会创建一个该对象,并通过ScheduledExecutorService创建守护线程定时执行。

但是该创建过程没有做并发控制,当请求并发大的时候,会创建很多个sessionValidationScheduler对象。虽然DefaultSessionManager对象中只保留了一个引用,但是ScheduledExecutorService创建守护线程中还维持了这些多余的sessionValidationScheduler对象。这样当执行周期到的时候,会有很多个线程一起将会话对象加载到内存,从而导致内存瞬时飙升。

解决方法很简单:将ExecutorServiceSessionValidationScheduler配置成bean,并注入到"sessionManager"bean中。这样就不会生成重复的SessionValidationScheduler对象。

  1. "sessionManager" class="org.apache.shiro.session.mgt.DefaultSessionManager">  
  2.     "globalSessionTimeout" value="3600000"/>  
  3.     "deleteInvalidSessions" value="true"/>  
  4.     "sessionValidationSchedulerEnabled" value="true"/>  
  5. "sessionValidationScheduler" ref="sessionValidationScheduler"/>  
  6.     "sessionDAO" ref="sessionDAO"/>  
  7. "sessionValidationScheduler" class="org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler">
  8. "interval" value="3600000"/>
  9.  "sessionManager" ref="sessionManager"/>

你可能感兴趣的:(Java)