jvm - Java 进程消耗 90% 的交换空间

标签 jvm tomcat7 swap

我有一个分配了 20GB 堆内存的应用程序。但即使堆内存几乎没有使用或少于 50%,我的服务器交换空间也完全用完了。 Java 进程消耗了 90% 的交换空间。

只有在重新启动应用程序并出现以下警告后,交换才会被释放。寻找根本原因以及由此产生的任何影响。如果交换空间已满,我的应用程序会无法启动吗?

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

There is insufficient memory for the Java Runtime Environment to continue. Native memory allocation (mmap) failed to map 17895718912 bytes for committing reserved memory.. Out of swap space or heap resource limit exceeded (check with limits or ulimit)? An error report with more information is generated, it is saved as a file at this location: /XX/myapp/apache-tomcat-7.0.90/bin/hs_err_pid86282.log 2020-01-14T05:17:18.742+0100 [INFO] [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker] Bean '(inner bean)#1814a032' of type [org.springframework.aop.aspectj.AspectJAroundAdvice] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) ***Warning: INFO: os::commit_memory(0x00000003fjgh0000, 17895718912, 0) failed; error='Not enough space' (errno=12) There is insufficient memory for the Java Runtime Environment to continue. Native memory allocation (mmap) failed to map 17895718912 bytes for committing reserved memory.. Out of swap space or heap resource limit exceeded (check with limits or ulimit)? An error report with more information is generated, it is saved as a file at this location:

我的 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 进程不仅仅仅来自堆内存,请观看 this for a good example .

现在,您说您有 28GB RAM,其中20GB仅用于堆。您不仅保留虚拟内存,还通过 AlwaysPreTouch 提交虚拟内存(我现在怀疑您是否理解它的作用)。因此,您的操作系统将 20GB RAM 映射到您的进程(简化解释)。

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

您的进程失败,并显示 native 内存分配(mmap)无法映射...,如上所述,这与堆无关。它在 native 内存中失败,这是!=堆。我也不知道您的应用程序的具体情况,但 -XX:+DisableExplicitGC 可能不是一个好的选择;相反,您可以通过 -XX:+ExplicitGCInvokesConcurrent 启用并发调用(如果您的 GC 支持)。

您似乎还在使用 CMS 垃圾收集器 - 已弃用。

关于jvm - Java 进程消耗 90% 的交换空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60112334/

相关文章:

ubuntu - 安装tomcat时如何解决安装错误

web-applications - 如何使用 SSL 启用我的 Web 应用程序?

java - 跟踪 java 字节码流

java - Java 中的初始 ArrayList 大小取决于内存?

java - 通过 JVM 参数设置 log4j 属性文件 - 为什么顺序很重要?

php - GWT、PHP 和 SSL 的最佳单服务器解决方案

c++ - 你如何在 c 中交换结构数组的元素?

algorithm - 向量的排列

c++ - 两个字符串的交换元素C++

java - Tomcat 日志显示错误的日期