我有一个 Spring 批处理应用程序,它消耗约16 GB内存和75%的CPU(4核X2.5Ghz),有时它抛出内存异常。
我想优化堆分配和垃圾收集,并尝试使用以下JVM选项,以便解决内存不足异常。
我无法理解其中的一些参数,因为我直接从一篇文章中复制粘贴
JAVA_OPTS="-服务器**-Xmx 20480 m-Xms 512 m**-XX:+使用ConcMarkSweepGC-XX:+使用ParNewGC-XX:+启用CMS类卸载-XX:+启用CMS并行备注-XX:CMS启动占用分数=30 -XX:+CMS增量模式-XX:+CMS增量调整-XX:并行CMS线程数=2 -XX:+使用CMS完整收集时压缩-XX:+禁用显式GC-XX:最大堆空闲比率=70 -XX:最小堆空闲比率=40-XX:最大保留阈值=0 -XX:新大小= 450 m-XX:最大新大小= 650 m”
它真的会优化堆分配和垃圾收集并解决内存不足异常吗?
3条答案
按热度按时间vhmi4jdf1#
首先,当进程抛出OOM错误时,您需要对进程进行堆转储。您可以通过添加
-XX:+HeapDumpOnOutOfMemoryError
JVM选项来完成此操作。在进行堆转储后,尝试使用以下任何工具来分析堆转储。找到内存中正在增长的对象,然后对其进行优化。堆转储分析工具包括:c9qzyr3d2#
当Java堆上没有足够的空间来分配对象时,或者如果Java进程将其98%以上的时间用于垃圾收集,并且如果它恢复的堆不到2%,并且到目前为止已经执行了最后5个垃圾收集周期,则通常会引发此错误。
我会首先使用Java分析器来确定哪些方法在堆上分配了大量对象,并确保它们在不再需要之后不再被引用。如果这不能解决问题,并且我已经确认我需要所有的对象,另一个选择是增加程序的最大堆大小。
hwamh0ep3#
阅读更多关于字符串不变性的内容,以及当您需要执行大量字符串操作时,为什么首选stringbuilder。
Java Why strings are immutable in java?中的字符串生成器-字符串缓冲区