java - 强制java内存不足..不一致的java行为

标签 java out-of-memory

我故意创建了以下类来导致内存不足错误

public class Test1
{
    public static void main(String[] args)
    {
        StringBuffer sb = new StringBuffer();
        while(true)
        {
            Test1 a = new Test1();
            sb.append(a.toString());
        }
    }
} 

正如我所料,上面的类(class)失败了,我想要的......

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
        at java.util.Arrays.copyOf(Unknown Source)
        at java.lang.AbstractStringBuilder.expandCapacity(Unknown Source)
        at java.lang.AbstractStringBuilder.append(Unknown Source)
        at java.lang.StringBuffer.append(Unknown Source)
        at Test1.main(Test1.java:10)

但是这个:

public class Test1
{
    public static void main(String[] args)
    {
        StringBuffer sb = new StringBuffer();
        while(true)
        {
            Test1 a = new Test1();
            System.out.println(sb.toString());
            sb.append(a.toString());
        }
    }
} 

不会崩溃。通过在控制台上一遍又一遍地打印对象地址,运行得很好。

我的问题是:

简单的 SOP 有何不同?

最佳答案

您关于不存在 OutOfMemoryError 的假设可能是不正确的。它只是被严重延迟了。在输出流上打印越来越大的字符串需要很长时间,以至于您的循环可能需要一个小时才能耗尽内存。

您可以通过仅每 10 次、100 次、1000 次打印来仔细检查这一点。您会发现生成的 IO 越少,错误发生得越早。也许您会在 jconsole 中看到这样的曲线:

enter image description here

正如您所看到的,堆正在缓慢但稳定地上升。即使我尝试强制垃圾回收(15:02 和 15:07),我也无法再释放所有内存。但由于我仍然只占堆的 5%,所以我现在将停止运行您的代码:-)

关于java - 强制java内存不足..不一致的java行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7319218/

相关文章:

java - 在 Java 中使用多个线程

c - 堆/静态、macOS 和 Linux 上的大 GB 数组

java - 如何在不构建项目两次的情况下通过 Travis CI 部署到 Heroku?

java - 如何在Hibernate中添加数据库更改的监听器?

java - android mapView 未解决

java.lang.AssertionError : Docker environment has more than 2GB free

java - 异常 java.lang.OutOfMemoryError : GC overhead limit exceeded with tree map

java - 如何编辑Java平台包(内置API)源代码?

java - Clover Java堆空间错误

java - 应用程序循环中出现OutOfMemoryError,如何做得更好?