Spring AspectJ AOP 和 redirect ModelAndView 导致的内存泄漏问题

今天遇到一个缓慢内存泄漏的问题, 经查, 与 Spring MVC 的 redirect 使用相关.

如果使用了 Spring 的 Spring AspectJ AOP 和 ModelAndView, 并且在 redirect 的时候, 是如下面的跳转, 就可能有缓慢内存泄漏的问题.
当 redirect 时候, redirect 的 URL 是变化的时候, 就会出现内存泄漏, 比如下面的代码:

 String redirectUrl = "id=" + String.valueOf(Math.random());
 return new ModelAndView(String.format("redirect:%s", redirectUrl));

原因是: 在页面解析的时候, 这个 ModelAndView 会被 Spring 重新生成一个 RedirectView, 这个 RedirectView 被 Spring 生成之后, 会执行一个 postProcessAfterInitialization 方法, 如果这时候是使用 AspectJ AOP, 那么 AspectJ 会把生成的一个 bean 放入一个 全局唯一的 ConcurrentHashMap里面, 放的时候以 bean.getClass() + beanName 作为 key. 然而对于 RedirectView, 这个 beanName 正是这个 redirect 的 URL, 如果它是一个变化的值, 那么就会持续添加. 代码:

@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
    if (bean != null) {
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        if (!this.earlyProxyReferences.contains(cacheKey)) {
            return wrapIfNecessary(bean, beanName, cacheKey);
        }
    }
    return bean;
}

发生添加的Stack trace 如下, 可以进行 debug 验证:
Debug_-<em>org_springframework_web_servlet_DispatcherServlet</em>-<em>RIDE_for_Raptor_2</em>-__Users_xiatian_Documents_workspaceSre.png

标签: none

添加新评论