我在尝试追踪这个OutOfMemoryError时非常糟糕,我真的很感激一些帮助。我的应用程序分为体系结构部分和一个模块,该模块使用Hibernate创建的数据库CRUD操作公开一些基本的REST WS。主体系结构具有记录和管理属性和配置的唯一作用(所有这些都由Spring处理)。
应用程序没有做任何如此花哨的事情,但仍然在使用Tomcat 7进行2-3次热重新部署之后我得到了OutOfMemoryError。我已经完成了一个Heap转储并用VisualVM打开它,这就是我所看到的:
正如您所看到的,我有很多字符串,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());
}
如果记录器不是原因,可能是由于我不知道的某些Spring / Hibernate / Tomcat /某些库?
如果您需要其他任何东西,比如Spring配置,请随时询问。
谢谢!
答案 0 :(得分:0)
问题与JEE webapps的热重新部署有关。不在Tomcat中,而是在任何JEE Servlet容器上。
这里有一个很好的解释:
答案 1 :(得分:0)
正如你所看到的,我有很多字符串,char []和byte []。真正操纵这种数据的唯一类是记录器,它是一个servlet-filter
这真的很难相信。 hibernate实体不包含单个字符串,HTTP请求永远不会存储在char []中,响应永远不会被缓冲,...
字符串是一种普遍存在的数据类型,几乎每个类路径中的每个库都会广泛使用它们,诀窍在于找到哪个库正在泄漏它们,以及原因。
要有效地分析堆转储,您应该使用的工具不仅列出了有多少对象,还分析了对象引用的图形,以找出哪些对象保持这些字符串的活动状态。大多数商业内存配置文件都做得很好。除此之外,开源Eclipse Memory Analyzer也非常好。自从我上次使用它已经有一段时间了,但是对于我最后一次内存泄漏,MAT的标准泄漏可疑报告正确识别了导致OutOfMemoryError的对象。