为了针对性研究堆内存溢出问题,专门准备了一段程序:
import java.util.ArrayList; import java.util.List; public class Jvm1_5 { public static void main(String[] args) { int i=0; try{ List<String> list=new ArrayList<>(); String a="hello"; while (true){ list.add(a); a=a+a; i++; } }catch (Throwable e){ System.out.println(i); e.printStackTrace(); } } }
得到如下结果:
26 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 Jvm1_5.main(Jvm1_5.java:13) Process finished with exit code 0
首先对内存溢出的提示是Java heap space,我们的程序在每一次循环中不段进行拼接,并且添加到我们的list中,内存并不会被释放,导致了堆内存溢出。
我们添加jvm参数-Xmx7m再运行:
17 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 Jvm1_5.main(Jvm1_5.java:13)
这次发现循环了17次,堆空间就不够了,这也引起我们的思考,有时候我们内存设置比较大,所以运行一段时间空间也还是发现不了。我们可以把内存设置小一点,就可以尽早暴露堆内存的问题。