4

我正在使用带有 maven 的码头服务器运行 Web 应用程序。该应用程序在列表映射中包含大量静态对象,导致 2.8GB 的​​物理内存使用量。几个小时后,服务器以最大 CPU 使用率挂起。这发生在没有任何用户交互或在服务器上发出请求的情况下。

我注意到在这几个小时内,虽然服务器运行良好,但内存慢慢减少到 1.7GB。我怀疑这可能是与垃圾收集相关的问题。

问题:

  1. 可能是 GC 在错误地收集或检查我的大型对象池及其引用时挂起?
  2. 我将如何调试和解决这个问题?

请注意,在 Windows 上我没有这个问题。一旦应用程序启动并填满它的池,它会占用 3.4GB 并保持完全相同而不会崩溃。

服务器启动及环境:

setenforce 0
export MAVEN_OPTS="-Xmx5120m -Xms5120m -XX:+UseConcMarkSweepGC -Xgcthreads1 -XX:MaxGCPauseMillis=2000 -XX:GCTimeRatio=10"
sudo nohup mvn -D jetty.port=80 jetty:run &

操作系统:

Ubuntu 12.04.1 LTS

爪哇:

OpenJDK Runtime Environment (IcedTea6 1.11.5) (6b24-1.11.5-0ubuntu1~12.04.1)
OpenJDK 64-Bit Server VM (build 20.0-b12, mixed mode)

马文:

Apache Maven 3.0.4

码头:

8.1.8.v20121106
4

1 回答 1

2

很难说是不是因为不正确的 GC 导致了系统挂起。我认为您可以采取一些措施来获取更多信息:

  1. 添加-verbose:gc -Xloggc:/home/admin/logs/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps到您的JVM 参数中,这些将帮助您找到更多关于 GC 的信息。
  2. 定期收集线程转储以查看应用程序在运行时发生的情况。
  3. 机器快要死机时获取内存转储,可以通过MAT分析。
  4. 当 CPU 达到峰值时,使用top -H -p<pid>找到支配线程并在线程转储中发现它们,然后您基本上可以找出哪一行代码做错了。

这是一篇非常好的文章How to Analyze Java Thread Dumps

于 2013-01-17T13:46:55.543 回答