为什么这个java程序总是以内存不足结束

时间:2018-01-16 08:34:48

标签: java garbage-collection

我的java版本如下。

ObservableArrayList

我的程序非常简单。代码如下。

java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)

我运行以下命令来运行此程序

import java.util.concurrent.ThreadLocalRandom;

public class Test {

    static class DummyObj {
        public String t1;
        public Integer t2;
        public Long t3;
        public Double t4;

        public DummyObj() {
            int i = ThreadLocalRandom.current().nextInt(10000);
            t1 = "t1t1t1" + i;
            t2 = 222 + i;
            t3 = 3333L + i;
            t4 = 44444.0 + i;
        }
    }

    void f1() {
        for (int i=0; i<100; ++i) {
            DummyObj t0 = new DummyObj();
            if (8 == ThreadLocalRandom.current().nextLong(1000000))
                System.out.println(t0.t3);
        }
    }

    public static void main(String... arg) {
        Test t0 = new Test();
        while (true) {
            t0.f1();
            try {
                Thread.sleep(2L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
};

程序总是因OutOfMemoryError崩溃。

有谁知道为什么gc无法释放内存?

除此之外我正在进行这个实验,以便了解Java垃圾收集器的工作原理(所以这不是某种&#34;生产代码&#34; - 它是意味着来显示GC&#34;做好自己的工作&#34;)。

1 个答案:

答案 0 :(得分:2)

首先,您正在运行具有8 MB内存的JVM。对于Java应用程序来说,这就像“无所事事”。

然后你正在以高费率创建新对象。是的,有一些人在睡觉,但你的代码仍然只是在创造垃圾。如果您的代码的唯一目的是创建垃圾 - 您希望任何垃圾收集器如何跟上它?

这就是重点:垃圾收集不是魔法。它仍然需要时间才能发生。当你结合

  • 开头的超级内存
  • 代码除了创建垃圾和睡眠外别无其他

您的应用程序迟早会耗尽内存。

当你声明你“想要学习”GC如何运作测试时...这个问题的答案更短:你做不到。垃圾收集是高级,复杂的主题。你绝对不能通过编写这样或那样的小测试用例来“学习”它的工作原理。现代Java垃圾收集器做不同事情的 zillions 。请记住:这项技术已有20多年的研究经验。您可能通过测试观察到的效果不会为您提供足够的信息来学习任何东西。你就像一个人试图在一个巨大的巨大房间里理解所有的东西 - 同时在外面,试图透过钥匙孔看看!

你必须在这里咬紧牙关 - 意思是:你必须学习文档和教程。在here上开始question或直接在SO上,这个问题有很多深入的答案。)