我在多个服务器上安装了JDK 8,堆大小不断增加,直到达到90%并导致应用程序失败。在此期间,多个GC运行,但老年代仍然保持增长,直到应用程序失败。目前的解决方法是重新启动Tomcat。我的服务器有15GB RAM和4核CPU。我的Java设置如下:
-Xms12036M -Xmx12036M -Xmn800M
这些值有什么建议吗?我原以为GC会处理它,但似乎老年代没有。我是Java的新手,不确定这是否表示内存泄漏或GC没有执行此操作。
我在多个服务器上安装了JDK 8,堆大小不断增加,直到达到90%并导致应用程序失败。在此期间,多个GC运行,但老年代仍然保持增长,直到应用程序失败。目前的解决方法是重新启动Tomcat。我的服务器有15GB RAM和4核CPU。我的Java设置如下:
-Xms12036M -Xmx12036M -Xmn800M
这些值有什么建议吗?我原以为GC会处理它,但似乎老年代没有。我是Java的新手,不确定这是否表示内存泄漏或GC没有执行此操作。
我认为您的参数没有问题。建议检查您的代码中是否存在内存泄漏。使用分析工具是一个好主意,但您也可以寻找泄漏模式。这里有一个非常好的收集资料:Creating a memory leak with Java
JVM的垃圾回收仅负责清理主程序没有引用的对象(包括“引用循环”)。
如果堆中有许多对象不能被GC收集,则可能导致OOM,有两种可能性:
这些对象在逻辑上是程序所需的:
您需要添加内存资源或更改程序流程以避免使用大量内存资源。
这些对象在逻辑上不再需要,但仍被主程序引用 (例如,对象不再需要,但未从列表中删除): 这是Java中的内存泄漏问题,是一个bug,您必须在程序中修复它。
尝试使用一些分析工具或跟踪代码以确定是否存在内存泄漏问题。
-Xmn800M
(800MB 的年轻代)对于 12GB 堆来说似乎是一个相当低的值。考虑直接取消该参数,并保留 -Xms12036M -Xmx12036M
参数。
请注意,您的老年代将继续增长,直到进行完整 GC。您会有很多次小的 GC,在前面的 800MB 上进行 GC,但不会在其余的 11.2GB 上进行 GC。因此,请尝试使用 Eclipse Memory Analysis 工具 比较堆转储。另外,尝试获取几个不同的堆转储。关注一下大小单调递增的对象。