Spring集成Shiro时内存溢出的问题分析
2016-05-29 03:17
671 查看
前段时间有一天系统访问量突然增加,系统每隔一两个小时就会由于内存瞬时飙升而宕机。查看内存dump文件发现其中Shiro的SimpleSession对象异常多。后来经分析才发现是由于使用Spring集成Shiro时配置不当导致的。当时的配置如下:
<bean id="sessionManager" class="org.apache.shiro.session.mgt.DefaultSessionManager">
<property name="globalSessionTimeout" value="3600000"/>
<property name="deleteInvalidSessions" value="true"/>
<property name="sessionValidationSchedulerEnabled" value="true"/>
<property name="sessionDAO" ref="sessionDAO"/>
</bean>
该配置中使用Shiro自带的用户会话超时校验功能,每一个小时执行一次该逻辑。
经过研究源代码发现有需要进行认证授权等验证的请求进入的时候,DefaultSessionManager对象(即上面配置的"sessionManager"bean)会判断其中的sessionValidationScheduler属性对象是否存在(该对象负责执行会话超时校验逻辑)。如果不存在,会创建一个该对象,并通过ScheduledExecutorService创建守护线程定时执行。
但是该创建过程没有做并发控制,当请求并发大的时候,会创建很多个sessionValidationScheduler对象。虽然DefaultSessionManager对象中只保留了一个引用,但是ScheduledExecutorService创建守护线程中还维持了这些多余的sessionValidationScheduler对象。这样当执行周期到的时候,会有很多个线程一起将会话对象加载到内存,从而导致内存瞬时飙升。
解决方法很简单:将ExecutorServiceSessionVa
4000
lidationScheduler配置成bean,并注入到"sessionManager"bean中。这样就不会生成重复的SessionValidationScheduler对象。
<bean id="sessionManager" class="org.apache.shiro.session.mgt.DefaultSessionManager">
<property name="globalSessionTimeout" value="3600000"/>
<property name="deleteInvalidSessions" value="true"/>
<property name="sessionValidationSchedulerEnabled" value="true"/>
<property name="sessionValidationScheduler" ref="sessionValidationScheduler"/>
<property name="sessionDAO" ref="sessionDAO"/>
</bean>
<bean id="sessionValidationScheduler" class="org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler">
<property name="interval" value="3600000"/>
<property name="sessionManager" ref="sessionManager"/>
</bean>
<bean id="sessionManager" class="org.apache.shiro.session.mgt.DefaultSessionManager">
<property name="globalSessionTimeout" value="3600000"/>
<property name="deleteInvalidSessions" value="true"/>
<property name="sessionValidationSchedulerEnabled" value="true"/>
<property name="sessionDAO" ref="sessionDAO"/>
</bean>
该配置中使用Shiro自带的用户会话超时校验功能,每一个小时执行一次该逻辑。
经过研究源代码发现有需要进行认证授权等验证的请求进入的时候,DefaultSessionManager对象(即上面配置的"sessionManager"bean)会判断其中的sessionValidationScheduler属性对象是否存在(该对象负责执行会话超时校验逻辑)。如果不存在,会创建一个该对象,并通过ScheduledExecutorService创建守护线程定时执行。
但是该创建过程没有做并发控制,当请求并发大的时候,会创建很多个sessionValidationScheduler对象。虽然DefaultSessionManager对象中只保留了一个引用,但是ScheduledExecutorService创建守护线程中还维持了这些多余的sessionValidationScheduler对象。这样当执行周期到的时候,会有很多个线程一起将会话对象加载到内存,从而导致内存瞬时飙升。
解决方法很简单:将ExecutorServiceSessionVa
4000
lidationScheduler配置成bean,并注入到"sessionManager"bean中。这样就不会生成重复的SessionValidationScheduler对象。
<bean id="sessionManager" class="org.apache.shiro.session.mgt.DefaultSessionManager">
<property name="globalSessionTimeout" value="3600000"/>
<property name="deleteInvalidSessions" value="true"/>
<property name="sessionValidationSchedulerEnabled" value="true"/>
<property name="sessionValidationScheduler" ref="sessionValidationScheduler"/>
<property name="sessionDAO" ref="sessionDAO"/>
</bean>
<bean id="sessionValidationScheduler" class="org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler">
<property name="interval" value="3600000"/>
<property name="sessionManager" ref="sessionManager"/>
</bean>
相关文章推荐
- Java EE 远程客户的访问EJB实现实例(Jboss wildfly)
- 详解依赖注入与自动装配
- 为什么Java byte 类型的取值范围是-128~127
- org.hyperic.sigar.SigarException: no sigar-x86-winnt.dll in java.library.path解决办法
- JAVA 各种数值类型最大值和最小值 Int, short, char, long, float,&nbs
- Java类的实例化过程
- 自动装配引起的Spring注入错误
- 四种生成和解析XML文档的方法详解(介绍+优缺点比较+示例)
- 学习javaweb的时候遇到的坑
- spring自定参数绑定----日期自动绑定
- Spring与JMX集成
- eclipse没有(添加)"Dynamic Web Project"选项的方法
- java布局学习 (三)
- Spring之JMX
- ZooKeeper源码导入Eclipse
- ubuntu eclipse如何导入项目
- java中几个常见的基础问题
- Java中关于链表的基本操作
- spring通过annotation注解注册MBean到JMX实现监控java运行状态
- ubuntu 增加eclipse桌面快捷方式