StringBuilder 导致堆内存溢出 Java heap space /GC overhead limit exceeded

时间:2025-02-21 13:36:43

原始问题描述:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at java.util.Arrays.copyOf(Arrays.java:3332)
	at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:124)
	at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:448)
	at java.lang.StringBuilder.append(StringBuilder.java:136)
	at testpkg.Main.decDfs(Main.java:230)

需求:
现在遇到的问题是在一个大量数据需要重复拼接,我遇到的是word文档需要一直拼接2000多页本地可以正常运行,但是发布到服务器后就会报 Java heap space 或者是 GC overhead limit exceeded的问题。

原因:
问题的原因在于无脑 append 的时候,扩充内存使得 StringBuilder 的长度超过了上限触发OOM,查看后发现 StringBuilder 实际能使用的大小和 JVM 。

解决方法:

  • 调大JVM参数,因为StringBuilder有时候没有到达上限,由于JVM堆空间太小,也会触发OOM
    将jvm的参数调大(我就是这个方法解决的)(我1048m没好用,直接上到2048m好用了)
    java -Xms2048m -Xmx2048m -Xss2048K -XX:PermSize=2048m -XX:MaxPermSize=2048m -jar

  • 重新计算最大所需空间,增加 StringBuilder 数量,提前分散放置字符串

  • 提前序列化部分结果,但是效率很低