我在试图追踪这个OutOfMemoryError时遇到了很大的困难,我真的很感谢你的帮助。我的应用程序分为架构部分和一个模块,该模块通过Hibernate进行的数据库CRUD操作公开了一些基本的REST WS。主架构只负责记录和管理属性和配置(所有这些都由Spring处理)。
这个应用程序并没有做任何花哨的事情,但在使用Tomcat7进行了2-3次热重新部署之后,我还是得到了一个OutOfMemoryError。我做了一个堆转储,并用VisualVM打开了它,下面是我看到的:

正如你所看到的,我有很多的字符串,char[]和byte[]。唯一真正处理这类数据的类是logger,它是一个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配置,请随时提出。
谢谢!
发布于 2016-05-06 00:20:08
这个问题与JEE webapps的热重新部署有关。不是在Tomcat中,而是在任何JEE Servlet容器中。
这里有一个很好的解释:
发布于 2016-05-06 00:48:39
正如你所看到的,我有很多的字符串,char[]和byte[]。唯一真正处理这类数据的类是logger,它是一个servlet过滤器
这真的很难相信。hibernate实体不包含单个字符串,HTTP请求永远不会存储在char[]中,响应永远不会缓冲,...
字符串是一种无处不在的数据类型,以至于类路径中的几乎每个库都会广泛使用它们,诀窍在于找出是哪个库泄漏了它们,以及原因。
为了有效地分析堆转储,您应该使用这样的工具,该工具不仅列出有多少对象,而且还分析对象引用的图形,以找出哪些对象使这些字符串保持活动状态。大多数商业内存配置文件都能很好地做到这一点。除此之外,开源的Eclipse Memory Analyzer也相当不错。距离我上次使用它已经有一段时间了,但对于我上一次的内存泄漏,MAT的标准泄漏可疑报告正确地识别了导致OutOfMemoryError的对象。
https://stackoverflow.com/questions/37055102
复制相似问题