Jvm Java进程占用90%的交换空间

Jvm Java进程占用90%的交换空间,jvm,tomcat7,swap,Jvm,Tomcat7,Swap,我有一个分配了20GB堆内存的应用程序。但是,即使堆内存的使用率很低或不到50%,我的服务器交换空间也会被完全耗尽。Java是消耗90%交换的进程 只有在使用以下警告重新启动应用程序后,才能释放交换。寻找根本原因和由此产生的任何影响。如果交换已完成,我的应用程序是否将无法启动 我在应用程序启动期间在日志中看到的警告: /XX/java/bin/java -Djava.util.logging.config.file=/XX/myapp/tomcat/conf/logging.properties

我有一个分配了20GB堆内存的应用程序。但是,即使堆内存的使用率很低或不到50%,我的服务器交换空间也会被完全耗尽。Java是消耗90%交换的进程

只有在使用以下警告重新启动应用程序后,才能释放交换。寻找根本原因和由此产生的任何影响。如果交换已完成,我的应用程序是否将无法启动

我在应用程序启动期间在日志中看到的警告

/XX/java/bin/java -Djava.util.logging.config.file=/XX/myapp/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -javaagent:/xx/myapp/newrelic/newrelic.jar -Djdk.tls.ephemeralDHKeySize=2048 -Xms20g -Xmx20g -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+AlwaysPreTouch -XX:+DisableExplicitGC -XX:+CMSIncrementalMode -XX:+CMSIncrementalPacing -Djava.net.preferIPv4Stack=true -Dignore.endorsed.dirs= -classpath /XX/myapp/tomcat/bin/bootstrap.jar:/XX/myapp/tomcat/bin/tomcat-juli.jar -Dcatalina.base=/XX/myapp/tomcat -Dcatalina.home=/XX/myapp/tomcat -Djava.io.tmpdir=/XX/myapp/tomcat/temp org.apache.catalina.startup.Bootstrap start
内存不足,Java运行时环境无法继续。 本机内存分配(mmap)映射17895718912字节以提交保留内存失败。。超出交换空间或堆资源限制(请检查限制或ulimit)? 生成包含更多信息的错误报告, 该文件保存在以下位置: /XX/myapp/apache-tomcat-7.0.90/bin/hs_err_pid86282.log 2020-01-14T05:17:18.742+0100[INFO][o.s.c.s.PostProcessorRegistrationLegate$BeanPostProcessorChecker]Bean'(内部Bean)#1814a032'类型[org.springframework.aop.aspectj.AspectJAroundAdvice]不适合由所有BeanPostProcessor处理(例如:不适合自动代理) ***警告:信息:os::提交_内存(0x00000003fjgh0000,17895718912,0)失败;error='没有足够的空间'(errno=12) 内存不足,Java运行时环境无法继续。 本机内存分配(mmap)映射17895718912字节以提交保留内存失败。。从…里面 超出交换空间或堆资源限制(请检查限制或ulimit)? 生成包含更多信息的错误报告, 该文件保存在以下位置:

我的JVM属性

/XX/java/bin/java -Djava.util.logging.config.file=/XX/myapp/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -javaagent:/xx/myapp/newrelic/newrelic.jar -Djdk.tls.ephemeralDHKeySize=2048 -Xms20g -Xmx20g -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+AlwaysPreTouch -XX:+DisableExplicitGC -XX:+CMSIncrementalMode -XX:+CMSIncrementalPacing -Djava.net.preferIPv4Stack=true -Dignore.endorsed.dirs= -classpath /XX/myapp/tomcat/bin/bootstrap.jar:/XX/myapp/tomcat/bin/tomcat-juli.jar -Dcatalina.base=/XX/myapp/tomcat -Dcatalina.home=/XX/myapp/tomcat -Djava.io.tmpdir=/XX/myapp/tomcat/temp org.apache.catalina.startup.Bootstrap start
交换使用检查每个进程时,其Java使用90%的交换

您的Java进程不仅是从堆内存中生成的,请注意

现在,您说您有
28GB
的RAM,其中您只为堆分配
20GB
。您不仅保留虚拟内存,而且还可以通过
始终使用spretouch
提交虚拟内存(我现在怀疑您是否理解这一点)。因此,您的操作系统将内存的
20GB
映射到您的进程(简化说明)

即使您看到只有
50%
被占用,您使用的垃圾收集器也不会将内存释放回操作系统,因此整个
20GC
始终被占用,不能被其他进程重复使用。因此,测量或监视堆是毫无意义的

您的进程失败,本机内存分配(mmap)未能映射…,如前所述,这与堆无关。它在本机内存中失败,这是
=堆。我也不知道您的应用程序的细节,但是
-XX:+DisableExplicitGC
可能不是一个好的选择;相反,您可以通过
-XX:+ExplicitGCInvokesConcurrent
启用并发调用(如果您的GC支持)


您似乎也在使用
CMS
垃圾收集器,这是不推荐使用的

非堆内存,即本机i/O缓冲区……此外,当您使用
-Xms20g-Xmx20g
-XX:+AlwaysPreTouch
时,您不能说只使用了堆的50%,因为这些选项精确地要求使20g堆看起来像是100%用于操作系统。您在机器上有多少内存?如何衡量实际内存/交换消耗?你能公布这些测量的结果吗?您是否尝试过使用JDK工具(如jstat、jmap、jcmd甚至分析器)来监视堆的使用情况?谢谢大家。我使用Newrelic监视JVM,可以看到使用了堆