WebSphere 7 - 过多的垃圾收集会导致内存不足吗?

WebSphere 7 - Can excessive Garbage Collection lead to out of memory?

问题: 超出本机内存异常并且想知道过多的垃圾收集是否会导致这种情况?此外,任何有关 GC 策略或调整的建议都会有所帮助。我不确定我拥有的东西是否值得改变。

很好的参考 Whosebug 问题: Which GC Policy to Use

规格:

初步分析:

  1. 我假设内存泄漏但是垃圾回收看起来正常,因为它回收内存
  2. 本机内存异常让我认为 VM 外部的内存正在耗尽,但我不确定是如何耗尽的。

附截图:

1.1 - 4 小时的堆利用率。每个绿色小垃圾桶代表一个主要的垃圾收集点。 1.2 上图中GC耗时。 1.3 内存不足异常期间堆利用率的情况。

异常:

EJB threw an unexpected (non-declared) ejb Exception data: java.lang.OutOfMemoryError: native memory exhausted at garbagecollection.mycode.test at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1658) at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1598) at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:149) at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:190) at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:125) at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:190) at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:125) at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:190) at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:125) at com.ibm.ws.webcontainer.filter.WebAppFilterChain._doFilter(WebAppFilterChain.java:80) at com.ibm.ws.webcontainer.filter.WebAppFilterManager.doFilter(WebAppFilterManager.java:908) at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:935) at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:503) at com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.handleRequest(ServletWrapperImpl.java:181) at com.ibm.ws.webcontainer.servlet.CacheServletWrapper.handleRequest(CacheServletWrapper.java:91) at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:875) at com.ibm.ws.webcontainer.WSWebContainer.handleRequest(WSWebContainer.java:1592) at com.ibm.ws.webcontainer.channel.WCChannelLink.ready(WCChannelLink.java:186) at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:453) at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleNewRequest(HttpInboundLink.java:515) at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.processRequest(HttpInboundLink.java:306) at com.ibm.ws.http.channel.inbound.impl.HttpICLReadCallback.complete(HttpICLReadCallback.java:83) at com.ibm.ws.ssl.channel.impl.SSLReadServiceContext$SSLReadCompletedCallback.complete(SSLReadServiceContext.java:1784) at com.ibm.ws.tcp.channel.impl.AioReadCompletionListener.futureCompleted(AioReadCompletionListener.java:165) at com.ibm.io.async.AbstractAsyncFuture.invokeCallback(AbstractAsyncFuture.java:217) at com.ibm.io.async.AsyncChannelFuture.fireCompletionActions(AsyncChannelFuture.java:161) at com.ibm.io.async.AsyncFuture.completed(AsyncFuture.java:138) at com.ibm.io.async.ResultHandler.complete(ResultHandler.java:204) at com.ibm.io.async.ResultHandler.runEventProcessingLoop(ResultHandler.java:775) at com.ibm.io.async.ResultHandler.run(ResultHandler.java:905) at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1646)

您收到的错误消息表明本机内存存在问题,即内存 堆之外。垃圾收集器不负责堆外内存,为什么垃圾收集器设置不能影响此错误。过多的垃圾收集不应导致本机内存问题(当然,除非 GC 中存在错误)。

如果没有更多信息,很难说是什么导致了这个特定的错误。我假设您的机器上至少有 12 GB 的可用 RAM?否则,您只是 运行 设置了一个对于可用内存来说太大的堆。

Java 中可能耗尽本机内存的一些示例:

  • 本机 (JNI) 代码中的泄漏

  • 直接分配很多ByteBuffers

或者可能没有泄漏,这种行为对于您的应用程序来说是预期的,您只需要允许更大的进程或购买更多内存。

解决问题的第一步是根据可能的进程大小限制检查进程大小。您可以简单地 运行 达到这样的限制而不会出现实际泄漏。

如果这不是问题,请跟踪一段时间内的进程大小,尤其是与可用内存相关的情况,看看您是否有 "leaky" 行为。

如果您真的认为自己存在本机内存泄漏,请确定您正在使用哪些使用 JNI 的库(例如 JDBC 驱动程序)并尝试将它们替换为仅 Java 的版本。此外,检查此类库中的已知内存泄漏错误以及您的 JVM 版本和 WebSphere 版本。

如果失败,您将不得不求助于本机内存泄漏故障排除工具。那是另一个问题。