【问题标题】:Java 8 with Jetty on linux memory issueJava 8 with Jetty 解决 Linux 内存问题
【发布时间】:2016-01-11 07:30:39
【问题描述】:

您能帮我解决以下问题吗:

上下文:

我们正在尝试将当前在生产中运行在 Java6(在 Glassfish 上)上的现有应用程序迁移到 Java8(在 Jetty9 上)设置。早些时候,我们能够在 Java7(在 jetty9)上成功迁移相同的设置。但是客户现在决定使用 Java 8。在这个过程中我们遇到了一些内存问题,具体如下:

问题描述:

启动 Jetty 服务器后,java 进程的初始 (RES) 内存使用量约为 5.5g。运行应用程序一段时间后,内存使用量缓慢上升并消耗机器上的最大可用物理内存(8g),最终导致服务器/系统崩溃。

此问题仅在 linux 环境中遇到。 Windows 环境下未发现此类问题。

Profiler 发现:

使用 VisualVMjconsole 监控服务器。在这两个分析器中,JVM 的内存(堆和非堆)使用量都低于分配的限制。

环境详情:

Java Version :    8
Server       :     Jetty 9.2.10
OS           :    linux on a virtual machine(Linux version 2.6.32-279.14.1.el6.x86_64 (mockbuild@c6b8.bsys.dev.centos.org) (gcc version 4.4.6 20120305 (Red Hat 4.4.6-4) (GCC) ) #1 SMP Tue Nov 6 23:43:09 UTC 2012
Java Options :        
        -Xms3072M

        -server

        -XX:+UnlockDiagnosticVMOptions

        -XX:+LogVMOutput

        -XX:+UseG1GC

        -XX:MaxGCPauseMillis=75

        -Xmx3072M

        -Xss1024K

        -XX:InitialCodeCacheSize=192M

        -XX:CodeCacheExpansionSize=3M

        -XX:CodeCacheMinimumFreeSpace=3M

        -XX:ReservedCodeCacheSize=600M

        -XX:MinMetaspaceExpansion=3M

        -XX:MaxMetaspaceExpansion=18M

        -XX:MaxMetaspaceSize=500M

        -XX:MaxDirectMemorySize=288M

        -XX:CompressedClassSpaceSize=512M

        -XX:ParallelGCThreads=12

        -XX:ConcGCThreads=4

        -Dsun.rmi.dgc.server.gcInterval=86400000

        -Dsun.rmi.dgc.client.gcInterval=86400000

PS:请不要将此标记为重复。我已经阅读了很多关于 stackoverflow 的答案,但没有解决或解决我的问题。

更新

我使用以下 Java 选项启动了 jetty,从那时起内存使用量在 4.5g-4.8g 之间(大约 142 小时)。在我看来它很稳定。我通过 java 选项标志(Xmx 和 MetaspaceSize)保留了大约 2g 的内存,但总是使用额外的 2.5g。这是 Linux 机器上 Java 8 的正常行为吗?

使用的 Java 选项:

-server
-XX:+UnlockDiagnosticVMOptions
-XX:+LogVMOutput
-XX:LogFile=../logs/jvm.log

-XX:+UseG1GC
-XX:MaxGCPauseMillis=75
-XX:ParallelGCThreads=12
-XX:ConcGCThreads=12
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-Xloggc:../logs/gc.log
-XX:NativeMemoryTracking=summary

-Xmx1500m
-Xss256k

-XX:MaxMetaspaceSize=512m

-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/opt/logs/jetty.hprof

-Dsun.rmi.dgc.server.gcInterval=86400000
-Dsun.rmi.dgc.client.gcInterval=86400000

感谢您的宝贵时间!

【问题讨论】:

  • 您是否在某处使用本机代码(明确地说,几乎每个 Java 程序都在后台使用大量本机代码)?就像对 openssl 的本机绑定,还是像 netty.io/wiki/native-transports.html 这样的 http 连接器?那里的内存泄漏不遵守 JVM 限制,因为内存不是由 JVM 管理的。 evanjones.ca/java-native-leak-bug.html 有一些提示如何查找这些问题
  • @zapl 感谢您的意见!我将在我的项目中检查本机绑定。
  • 我认为 MaxDirectMemorySize 不适用于 mmaped 文件,仅适用于 ByteBuffer.allocateDirect(),因此请检查您的堆转储中的 DirectByteBuffer 实例并计算它们的容量。

标签: java linux memory-management java-8 jvm-arguments


【解决方案1】:

这似乎是 Java8/9 中的一个问题,它在 Jetty 中表现出来,因为注释模块会扫描 jar 并存在内存泄漏。参考。 https://github.com/eclipse/jetty.project/issues/575。我的一个解决方案(因为我不使用 Jetty 注释)是通过注释掉 jetty/modules/annotations.mod 中的行来禁用注释模块。所以 tie 文件看起来像这样:

#
# Jetty Annotation Scanning Module
#

[depend]
# Annotations needs plus, and jndi features
plus

[lib]
# Annotations needs jetty annotation jars
lib/jetty-annotations-${jetty.version}.jar
# Need annotation processing jars too
#lib/annotations/*.jar

[xml]
# Enable annotation scanning webapp configurations
#etc/jetty-annotations.xml

编辑 1 - 替代解决方案

关闭所有注释扫描可能过于激烈,它也转向 jsp,因为它是依赖的。另一种方法是提供一个 Web 应用程序上下文,该上下文使用一种模式来限制扫描。将其保存在 xml 中,并将其与 war 一起部署在 webapps 中,或者将其包含在 war 中。

<Configure class="org.eclipse.jetty.webapp.WebAppContext">
   <Set name="contextPath">/[myApp]</Set>
   <Set name="war">/[DIRECTORY]/[myApp[.war</Set>
   <Call name="setAttribute">
      <Arg>org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern</Arg>
      <Arg>SCAN-NO-JARS</Arg>
    </Call>
</Configure>

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-19
  • 2010-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-23
  • 1970-01-01
相关资源
最近更新 更多