Java 8和Jetty在linux内存问题上的应用

Java 8和Jetty在linux内存问题上的应用,java,linux,memory-management,java-8,jvm-arguments,Java,Linux,Memory Management,Java 8,Jvm Arguments,你能帮我解决以下问题吗 背景: 我们正在尝试将现有的应用程序迁移到Java8(Jetty9)设置中,该应用程序目前正在生产中的Java6(Glassfish)上运行。早些时候,我们能够在Java7(jetty9)上成功地迁移相同的设置。但是客户决定现在就使用Java8。在此过程中,我们遇到了一些内存问题,以下是详细信息: 问题描述: 启动Jetty服务器后,java进程的初始(RES)内存使用量约为5.5g。运行应用程序一段时间后,内存使用率缓慢上升,并消耗机器上的最大可用物理内存(8g),最终

你能帮我解决以下问题吗

背景:

我们正在尝试将现有的应用程序迁移到Java8(Jetty9)设置中,该应用程序目前正在生产中的Java6(Glassfish)上运行。早些时候,我们能够在Java7(jetty9)上成功地迁移相同的设置。但是客户决定现在就使用Java8。在此过程中,我们遇到了一些内存问题,以下是详细信息:

问题描述:

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

只有在linux环境中才会遇到此问题。在Windows环境中未发现此类问题

探查器发现:

使用VisualVM和jconsole监视服务器。在这两个分析器中,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
注:请不要将此标记为重复。我已经阅读了很多关于stackoverflow的答案,但是没有任何东西解决我的问题

更新

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

使用的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

谢谢你的时间

这似乎是Java8/9中的一个问题,它在Jetty中表现出来,因为annotations模块扫描JAR并存在内存泄漏。参考。我的一个解决方案(因为我不使用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,因此也会导致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>

/[我的应用程序]
/[目录]/[myApp[.war]
org.eclipse.jetty.server.webapp.webinIncludeJarPattern
扫描器

您是否在某处使用本机代码(显然,几乎每个java程序都在幕后使用大量本机代码)?像openssl的本机绑定,或者像http连接器?内存泄漏不遵守JVM限制,因为内存不是由JVM管理的。有一些关于如何查找这些的提示problems@zapl感谢您的输入!我将在我的项目中检查本机绑定。我认为
MaxDirectMemorySize
不适用于mmaped files,仅适用于
ByteBuffer.allocateDirect()
,因此请检查堆转储中的
DirectByteBuffer
实例,并统计它们的容量。我自己也在努力解决这个问题,请参阅相关问题。我最初认为这是一个纯Java问题。