我们知道堆中存放的是对象,对象不被引用就会被垃圾收集回收掉。但是如果对象一直存在强引用,那么就会一直存活,当存活对象达到一定数量时,就会把堆内存占满,从而发生堆内存溢出错误。比如有这样一段代码:逻辑是每次都往集合中添加一个字符串对象,然后字符串进行一次拼接。
public class Demo1 { public static void main(String[] args) { int count = 0; StringBuilder sb = new StringBuilder(); List<String> list = new ArrayList<>(); String a = "hello"; try { while (true) { list.add(a); sb.append(a); count++; } } catch (Throwable e) { e.printStackTrace(); System.out.printf("count: %d", count); } } }
运行一会后报错:“java.lang.OutOfMemoryError: Java heap space”
我们用参数 -Xmx 对堆内存进行设置再运行下程序,同样的错误,只不过循环次数变少了。
我们可以在控制台输入命令 “jvisualvm”来查看堆内存的变化,要在Java VisualVM 中安装Visual GC 插件。运行某个java程序,点击左边的进程就可以查看堆内存各个区的变化了。