org.springframework.web.servlet.view.InternalResourceViewResolver 堆内存高问题

Spring使用 org.springframework.web.servlet.view.InternalResourceViewResolver 堆内存高问题

通过
Eclipse Memory Analyzer (http://www.eclipse.org/mat/)分析工具如下,堆内存中50.51%
是由InternalResourceViewResolver 产生的。

我当前使用的Spring版本是:Spring 3.1.1.RELEASE

One instance of "org.springframework.web.servlet.view.InternalResourceViewResolver" loaded by"org.apache.catalina.loader.WebappClassLoader @ 0x6e0024ca0" occupies2,342,803,136 (50.51%) bytes.
The memory is accumulated in one instance of"java.util.HashMap$Entry[]" loaded by"<system class loader>".

Keywords

org.springframework.web.servlet.view.InternalResourceViewResolver

java.util.HashMap$Entry[]

org.apache.catalina.loader.WebappClassLoader @ 0x6e0024ca0

在经过对线上的服务监控,发现系统发生了很多次的full gc,为什么频繁的Full GC不能回收掉的呢;原因是大量存活对象对HashMap持有强引用关系导致的。

JVM内存对象回收策略是经过GC ROOT可达性分析,当一个对象经过GC Root 不可达时,说明这个对象已经dead,下次就就可以被回收掉。

接下来我们从代码中分析下,看是什么原因导致的。

#我想做JAVA的同学,以下代码是不是感觉很熟悉,单从这方法看是不是觉得没有问题.....

@RequestMapping(value = "/index.do",params="userId")
	public ModelAndView index(String userId,ModelAndView mv) {
	  // TODO 业务处理...
	    mv.setViewName("redirect:/your_uri.do?userId="+userId);
	    return mv;
	}

那么我们在看下Spring对这个返回重定向的处理方式吧

在InternalResourceViewResolver的父类AbstractCachingViewResolver

 public View resolveViewName(String viewName, Locale locale) throws Exception {
    if (!isCache()) {
      return createView(viewName, locale);
    } else {
      Object cacheKey = getCacheKey(viewName, locale);
      synchronized (this.viewCache) {
        View view = this.viewCache.get(cacheKey);
        if (view == null && (!this.cacheUnresolved || !this.viewCache.containsKey(cacheKey))) {
          // Ask the subclass to create the View object.
          view = createView(viewName, locale);
          if (view != null || this.cacheUnresolved) {
            this.viewCache.put(cacheKey, view);
            if (logger.isTraceEnabled()) {
              logger.trace("Cached view [" + cacheKey + "]");
            }
          }
        }
        return view;
      }
    }
  }

在这里Spring 使用viewName+locale 作为Cache key 将创建的View ,Cache到HashMap了,避免每次重新创建View。以下就是Spring viewCache 实例对象源码

 /** Map from view key to View instance */
  private final Map<Object, View> viewCache = new HashMap<Object, View>();

由于我们return  ModelAndView 对象的URI 中存在动态参数,每个用户返回的URI都不一样,所有导致Cache Key无法命中,进而创建大量View ,Cache到viewCache.

"redirect:/your_uri.do?userId="+userId

如果需要使用Spring重定向建议采用RedirectView 处理,例如:

  @RequestMapping(value = "/index.do", params = "userId")
  public RedirectView index(RedirectView mv,String userId) {
    // TODO 业务处理
    UriComponentsBuilder builder = UriComponentsBuilder.fromPath("/xxx.do");
    builder.queryParam("userID", userId);
    mv.setUrl(builder.build().encode().toUriString());
    return mv;
  }
时间: 2024-11-05 18:48:21

org.springframework.web.servlet.view.InternalResourceViewResolver 堆内存高问题的相关文章

org.springframework.web.servlet.view.InternalResourceViewResolver

http://blog.csdn.net/superdog007/article/details/28857495 我们在controller里面经常这样return一个ModelAndView: return new ModelAndView('user', 'model', model); DispatcherServlet靠ViewResolver把user解析为/WEB-INF/jsp/user.jsp: 常用的ViewResolver: InternalResourceViewReso

org.springframework.web.servlet.PageNotFound

2017-07-11 16:36:13.489 WARN [http-nio-8032-exec-16]org.springframework.web.servlet.PageNotFound -Request method 'POST' not supported 2017-07-11 16:37:30.491 WARN [http-nio-8032-exec-48]org.springframework.web.servlet.PageNotFound -Request method 'PO

org.springframework.web.servlet.DispatcherServlet--Spring的前置控制器简介

Struts有一个ActionServlet,用来完成前置控制器(分发器)的功能.其实,所有MVC框架都有一个Servlet来完成这个功能,Spring也不例外,Spring中的前置控制器(分发器)就是DispatcherServlet. 在百度百科这样介绍它的作用: DispatcherServlet是前置控制器,配置在web.xml文件中的.拦截匹配的请求,Servlet拦截匹配规则要自已定义,把拦截下来的请求,依据相应的规则分发到目标Controller来处理,是配置spring MVC的

org.springframework.web.servlet.DispatcherServlet报错

搭建springmvc时,出现org.springframework.web.servlet.DispatcherServlet错误.检查了MAVEN依赖,包已下载好了,但就是找不到-- java.lang.ClassNotFoundException 重新检查项目的 web deployment assembly ,发现没有将maven依赖加入到其中,重新将其中所有的jar包加入.重启Tomcat.报错解决.

[org.springframework.web.servlet.PageNotFound] -No mapping found for HTTP request with URI [/homework/js/jquery-1.7.2.min.js] in DispatcherServlet with name &#39;SpringMVC&#39;

先上解决方案:对于上面出现的问题,查看了很多相关的博客,论坛.最后实在Spring-mvc.xml这个配置文件里加入了如下两行: 1 <mvc:annotation-driven /> 2 <mvc:default-servlet-handler /> 问题描述: 由于项目需要Ajax,于是在jsp的head里加入了如下代码: 1 <script type="text/javascript" src="/homework/js/jquery-1.

java.lang.ClassNotFoundException: org.springframework.web.servlet.DispatcherServlet

新建Maven 项目的时候报错: java.lang.ClassNotFoundException: org.springframework.web.servlet.DispatcherServlet java.lang.ClassNotFoundException: org.springframework.web.servlet.DispatcherServlet at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappC

springmvc报错 org.springframework.web.servlet.DispatcherServlet

在写springMVC时,导入所有需要的包后,运行程序,控制台报以下错误: 严重: Servlet [springDispatcherServlet] in web application [/SpringMVC-1] threw load() exception java.lang.ClassNotFoundException: org.springframework.web.servlet.DispatcherServlet at org.apache.catalina.loader.Web

org.springframework.web.servlet.PageNotFound - No mapping found for HTTP request with URI [XXX] in DispatcherServlet with name &#39;springMVC&#39;

在web.xml中添加 <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.ico</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.png<

eclipse里面配置spring,提示java.lang.ClassNotFoundException:org.springframework.web.servlet.Dispatcher错误

在eclipse里面创建了一个Dynamic 项目,用到spring,一直提示java.lang.ClassNotFoundException: org.springframework.web.servlet.Dispatcher 错误, 后来又提示java.lang.NoClassDefFoundError: org/springframework/context/ApplicationConte 后来新建了一个项目,然后结构什么的都没有改变就可以正常运行了: 对比了一下,发现可能的原因有以下