在我参与的几乎所有大型Java项目中,我都注意到应用程序的服务质量会随着容器的正常运行时间而降低。这很可能是由于代码中的内存泄漏。
解决此问题的正确方法显然是追溯到问题的根本原因,并修复代码中的漏洞。解决问题的快速而肮脏的方法只是重新启动Tomcat(或您正在使用的任何servlet容器)。
这是我的三个问题:
假设您选择通过跟踪问题的根本原因(内存泄漏)来解决问题,那么您将如何收集数据以放大问题?
假设您只是通过简单地重新启动容器来选择一种快速而肮脏的方法来加快处理速度,那么您将如何收集数据以选择最佳的重新启动周期?
您是否能够在更长的时间内部署和运行项目,而无需重新启动servlet容器以恢复快照?还是偶然的servlet重新启动但必须接受?
使用堆转储,jmap并使用Eclipse Memory Analyzer加载转储。在这里,您可以分析哪些对象消耗了最多的内存,哪些“根”阻止了其他对象的收集,等等。
jmap
还有其他堆分析程序,例如jhat,但是我发现EMA是最快,最好的(免费)解决方案。
jhat
使用JMX监视堆大小以及其他堆和GC统计信息。
您是否能够在更长的时间内部署和运行项目,而无需重新启动servlet容器以恢复快照?
是。通过避免/修复内存泄漏。