Java/Tomcat堆大小问题

4
我不是Java开发人员,但有一个应用程序需要处理。这是一个运行在Tomcat容器中的Web服务端应用程序。用户从客户端应用程序访问它。用户经常抱怨它的速度很慢,而且这个应用程序大约每周需要重启两次,因为情况变得非常糟糕。之前的开发人员告诉我,随着时间的推移,应用程序会因为加载更多数据而耗尽内存,最终全部时间都花费在垃圾收集上。同时,Tomcat的Heap Size设置为6GB。该服务器本身具有32GB的RAM。将Heap Size增加到16GB是否有害?似乎这是解决问题的简单方法,但我不是Java专家。

1
也许你应该弄清楚你想要“永久”缓存的数据总大小。否则看起来你需要一个更好的缓存解决方案(Ehcache)。 - Adam Gent
5个回答

5
你应该找出内存泄漏并进行修复,而不是增加堆空间。这只是一个临时措施。
你应该配置Tomcat在出现错误时转储堆,然后在崩溃后使用其中任何一种工具分析堆。你可以计算所有类的保留大小,这应该为你提供一个非常清晰的问题图像。
在我的个人资料中,我有一篇关于此事的博客文章,因为我最近也必须这样做。

1
如果出现@angryhacker这种情况,那么就说明程序有误。在正常操作下,你的应用程序总是会在一段时间后崩溃。你应该缓存适量的数据,而不是所有数据永久保存。 - hvgotcodes
@hvgotcodes,如果机器上有32GB的RAM,并且所有数据都可以放入10GB中,为什么不一直缓存所有数据呢?我可以理解如果我在内存受限的机器上,但我不是。所以回到我的最初问题,将堆大小增加到16GB会有什么危害吗? - AngryHacker
@angryhacker,你在最初的问题中没有提到所有数据都是10GB。你可以尝试一下。你使用的是64位的Java吗?32位无法访问10GB的内存。 - hvgotcodes
@hvgotcodes,32位Java也无法访问6GB :). 是的,这是64位Java,并且数据每年增加约500MB,因此我认为16GB应该可以使用一段时间。 - AngryHacker
@hvtgotcodes:“你应该找出漏洞并修复它,而不是增加更多的堆空间。”... 在现实世界中,有时候你没有那个奢侈:我们这里是一家价值数十亿美元的公司,在生产环境中,我们依赖于一个经常崩溃的Tomcat Web服务。负责此服务的服务器已经超载,他们根本没有时间/人力来解决问题。结果呢?一个不停运行的shell脚本监控JVM的状态,并在事情变得混乱时重新启动Tomcat。当然,这很糟糕。欢迎来到现实世界。 - SyntaxT3rr0r
显示剩余6条评论

2

不,将堆大小增加到16GB并没有任何危害。


1
之前的开发者告诉我,应用程序会因为随着时间的推移加载更多数据而简单地耗尽内存。
这看起来像是一个内存泄漏,是应用程序中的严重错误。如果你将可用内存从6 GB增加到16 GB,你仍然需要重新启动应用程序,只不过频率更低。一些有经验的开发者应该在运行时查看应用程序堆(参考 hvgotcodes 的建议)并修复应用程序。

我向您保证,只要应用程序有足够的内存来加载所有数据,它就不会耗尽内存。没有内存泄漏。我已经删除了大部分数据并在我的机器上尝试过,它可以正常工作。然而,这是一回事在本地尝试,而是另一回事当成千上万的用户使用时。 - AngryHacker

1
要解决这些问题,您需要进行性能测试。 这包括CPU和内存分析。 JDK(6)捆绑了一个名为VisualVM的工具,在我的Mac OS X机器上,这默认位于路径上,称为“jvisualvm”。 它是免费的并且捆绑在一起,因此这是一个开始的地方。
接下来是NetBeans Profiler(netbeans.org)。 它做更多的内存和CPU分析。 它也是免费的,但有点更复杂。
如果您能花钱,我强烈推荐YourKit(http://www.yourkit.com/)。 它不是非常昂贵,但它具有很多内置诊断功能,使得更容易找出问题所在。
你唯一不能做的事情就是假设只需添加更多内存即可解决问题。 如果是泄漏,添加更多内存可能只会使其在重新启动之间运行得更糟。

1
我建议您使用像JProfiler、VisualVM、jConsole、YourKit等性能分析工具。您可以对应用程序进行堆转储,并分析哪些对象占用了内存。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接