【发布时间】:2017-05-24 03:40:24
【问题描述】:
我正在运行 Java Web 应用程序(Play Framework)的多个实例。 Web 应用程序运行的时间越长,在我重新启动 Web 应用程序之前可用的内存就越少。有时我会遇到 OutOfMemory 异常。 我正在努力寻找问题所在,但我得到了很多相互矛盾的信息,所以我很难找到源头。
这是信息:
- Ubuntu 14.04.5 LTS,12 GB RAM
- OpenJDK 运行时环境(内部版本 1.8.0_111-8u111-b14-3~14.04.1-b14)
- OpenJDK 64 位服务器 VM(内部版本 25.111-b14,混合模式)
编辑: 以下是 JVM 设置:
- -Xms64M
- -Xmx128m
- -服务器
- (我不能 100% 确定这些参数是否正确传递给 JVM,因为我使用的是带有
start-stop-daemon的 /etc/init.d 脚本,它启动了启动 JVM 的播放框架脚本)
这是,我如何使用它:
start() {
echo -n "Starting MyApp"
sudo start-stop-daemon --background --start \
--pidfile ${APPLICATION_PATH}/RUNNING_PID \
--chdir ${APPLICATION_PATH} \
--exec ${APPLICATION_PATH}/bin/myapp \
-- \
-Dinstance.name=${NAME} \
-Ddatabase.name=${DATABASE} \
-Dfile.encoding=utf-8 \
-Dsun.jnu.encoding=utf-8 \
-Duser.country=DE \
-Duser.language=de \
-Dhttp.port=${PORT} \
-J-Xms64M \
-J-Xmx128m \
-J-server \
-J-XX:+HeapDumpOnOutOfMemoryError \
>> \
$LOGFILE 2>&1
我现在正在挑选网络应用的实例:
htop 显示 4615M 的 VIRT 和 338M 的 RES。
当我使用jmap -dump:live,format=b,file=mydump.dump <mypid> 创建堆转储时,文件只有大约 50MB。
当我在 Eclipse MAT 中打开它时,概览显示“20.1MB”的已用内存(“保持无法访问的对象”选项设置为 ON)。
那么如何在 Eclipse MAT 中将 htop 中显示的 338MB 缩小到 20.1MB 呢?
我认为这与 GC 无关,因为无论我等待多长时间,htop 总是显示这个内存量,它永远不会下降。
事实上,我会假设我的简单应用使用的空间不超过 20MB,也许是 30MB。
我用 Eclipse MAT 与年龄差异为 4 小时的堆转储进行比较,我没有看到对象有任何显着增加。
PS:我添加了-XX:+HeapDumpOnOutOfMemoryError 选项,但我必须等待 5-7 天才能再次发生。我希望您能帮助我解释我的数字,并早日找到问题。
谢谢你, 舒贝
【问题讨论】:
-
将你的JVM的参数添加到问题中。堆栈内存分配 (-Xss)、初始堆大小 (-Xms)、最大堆大小 (-Xmx) 等。请记住,Java 进程的总内存不仅仅包括其堆大小。此外,您不必等待几天让 JVM 在 OutOfMemoryError 上崩溃 - 只需减少堆大小,它应该会更快地发生。然后查看堆栈跟踪,因为它可能会为您提供有关代码中分配失败的确切位置的线索。
-
您是否尝试使用 JVisualVM 之类的工具来实时观看更改? VM 中的哪一部分内存不断增加?
-
谢谢!我添加了 JVM 参数。是的,我可以更早地引发 OutOfMemory 错误,你是对的。但如果可能的话,我想在问题发生之前找到它。我不能使用 JVisualVM,因为这是一台远程机器。谢谢大家的意见!!
-
@schube jvisualvm 可以连接到远程主机。它还打开自动生成的堆转储 (-XX:+HeapDumpOnOutOfMemoryError) 或使用 jmap 命令。
-
今天我用VisualVM连接到远程主机。我可以确认,我的 JVM 参数已正确传递给 JVM。此外,堆具有预期的最大大小。元空间已使用 99%。这是我的问题吗?见这里:imgur.com/a/sCGgw HTOP 仍然显示 380MB RES。谢谢!
标签: memory java-8 playframework-2.5