2016-05-05 49 views
0

我在试图追踪这个OutOfMemoryError时遇到了很糟糕的情况,我非常感谢您的帮助。我的应用程序被分成了体系结构部分和一个模块,这些模块公开了一些基本的REST WS和由Hibernate制作的数据库CRUD操作。主体系结构具有记录和管理属性和配置的唯一角色(所有这些都由Spring处理)。追踪OutOfMemoryError

应用程序没有做任何事情,但仍然在2-3热重新部署与Tomcat 7后我得到一个OutOfMemoryError。我做了一个堆转储与VisualVM的打开了它,这是我所看到的:

enter image description here

正如你所看到的,我有很多串,的char []和byte []左右。真正操纵这种数据的唯一类是它是一个Servlet过滤器只有这样的记录:

@Override 
public void doFilter(ServletRequest request, ServletResponse response, 
     FilterChain chain) throws IOException, ServletException { 

     HttpServletRequest httpServletRequest = (HttpServletRequest) request; 
     HttpServletResponse httpServletResponse = (HttpServletResponse) response; 

     Map<String, String> requestMap = this 
       .getTypesafeRequestMap(httpServletRequest); 
     BufferedRequestWrapper bufferedRequest = new BufferedRequestWrapper(
       httpServletRequest); 
     BufferedResponseWrapper bufferedResponse = new BufferedResponseWrapper(
       httpServletResponse); 

     final StringBuilder logMessage = new StringBuilder(
       "REST Request - ").append("[HTTP METHOD:") 
       .append(httpServletRequest.getMethod()) 
       .append("] [PATH INFO:") 
       .append(httpServletRequest.getRequestURI()) 
       .append("] [REQUEST PARAMETERS:").append(requestMap) 
       .append("] [REQUEST BODY:") 
       .append(bufferedRequest.getRequestBody()) 
       .append("] [REMOTE ADDRESS:") 
       .append(httpServletRequest.getRemoteAddr()).append("]"); 
     long startTime = System.currentTimeMillis(); 
     chain.doFilter(bufferedRequest, bufferedResponse); 
     long elapsed = System.currentTimeMillis() - startTime; 
     logMessage.append(" [RESPONSE:") 
       .append(bufferedResponse.getContent()) 
       .append("] [ELAPSED TIME:").append(elapsed).append("ms]"); 
     log.debug(logMessage.toString()); 
} 

当记录器是不是这个原因,可能是由于某些春/休眠/ Tomcat的/我不知道的一些图书馆?

如果您需要其他任何东西,比如Spring配置,请随时询问。

谢谢!

+0

什么是你的tomcat内存设置(Xmx,PermSize)? –

+0

当Tomcat作为应用程序服务器启动时,是否尝试为Web应用程序分配更多内存?还试图找出是否“一个支配者对象”创建并持有许多引用(我在Hibernate是原因时遇到过一个案例) – dumitru

回答

0

该问题与JEE webapps的热重新部署有关。不是在Tomcat中,而是在任何JEE Servlet容器中。

有在这里讨论一个很好的解释:

What makes hot deployment a "hard problem"?

+1

除了仅作为链接回答之外,该博文显得相当过时。具体来说,它要求设置Java 8中不再存在的JVM参数,并且Java 7已超过一年现已终止。 – meriton

0

正如你所看到的,我有很多串,的char []和byte []左右。唯一真正处理这种数据的类是记录器,它是一个servlet-过滤器

这真的很难相信。 hibernate实体不包含单个字符串,HTTP请求永远不会存储在char []中,响应永远不会被缓冲,...

字符串是一种无处不在的数据类型,几乎您的类路径中的每个库都将使用它们广泛而言,诀窍在于找出哪个库泄漏了它们,以及为什么。

为了有效地分析堆转储,您应该使用一个不仅列出有多少对象的工具,还要分析对象引用的图形以找出哪些对象正在使这些字符串保持活动状态。大多数商业内存配置文件都做得很好。除此之外,开源Eclipse Memory Analyzer也不错。自从我上次使用它以来已经有一段时间了,但是对于最后一次内存泄漏,MAT的标准泄漏可疑报告正确识别了导致OutOfMemoryError的对象。