WebSphere 7 - 过多的垃圾收集会导致内存不足吗?
WebSphere 7 - Can excessive Garbage Collection lead to out of memory?
问题: 超出本机内存异常并且想知道过多的垃圾收集是否会导致这种情况?此外,任何有关 GC 策略或调整的建议都会有所帮助。我不确定我拥有的东西是否值得改变。
很好的参考 Whosebug 问题:
Which GC Policy to Use
规格:
- 服务器环境:Websphere 版本 7
- GC 策略:默认 (optthruput)
- Java 1.5
- 堆:8 GB
- 运行 在虚拟机中
- 分析工具:App Dynamics
初步分析:
- 我假设内存泄漏但是垃圾回收看起来正常,因为它回收内存
- 本机内存异常让我认为 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) 代码中的泄漏
直接分配很多ByteBuffer
s
或者可能没有泄漏,这种行为对于您的应用程序来说是预期的,您只需要允许更大的进程或购买更多内存。
解决问题的第一步是根据可能的进程大小限制检查进程大小。您可以简单地 运行 达到这样的限制而不会出现实际泄漏。
如果这不是问题,请跟踪一段时间内的进程大小,尤其是与可用内存相关的情况,看看您是否有 "leaky" 行为。
如果您真的认为自己存在本机内存泄漏,请确定您正在使用哪些使用 JNI 的库(例如 JDBC 驱动程序)并尝试将它们替换为仅 Java 的版本。此外,检查此类库中的已知内存泄漏错误以及您的 JVM 版本和 WebSphere 版本。
如果失败,您将不得不求助于本机内存泄漏故障排除工具。那是另一个问题。
问题: 超出本机内存异常并且想知道过多的垃圾收集是否会导致这种情况?此外,任何有关 GC 策略或调整的建议都会有所帮助。我不确定我拥有的东西是否值得改变。
很好的参考 Whosebug 问题: Which GC Policy to Use
规格:
- 服务器环境:Websphere 版本 7
- GC 策略:默认 (optthruput)
- Java 1.5
- 堆:8 GB
- 运行 在虚拟机中
- 分析工具:App Dynamics
初步分析:
- 我假设内存泄漏但是垃圾回收看起来正常,因为它回收内存
- 本机内存异常让我认为 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) 代码中的泄漏
直接分配很多
ByteBuffer
s
或者可能没有泄漏,这种行为对于您的应用程序来说是预期的,您只需要允许更大的进程或购买更多内存。
解决问题的第一步是根据可能的进程大小限制检查进程大小。您可以简单地 运行 达到这样的限制而不会出现实际泄漏。
如果这不是问题,请跟踪一段时间内的进程大小,尤其是与可用内存相关的情况,看看您是否有 "leaky" 行为。
如果您真的认为自己存在本机内存泄漏,请确定您正在使用哪些使用 JNI 的库(例如 JDBC 驱动程序)并尝试将它们替换为仅 Java 的版本。此外,检查此类库中的已知内存泄漏错误以及您的 JVM 版本和 WebSphere 版本。
如果失败,您将不得不求助于本机内存泄漏故障排除工具。那是另一个问题。