Java 模拟中的内存泄漏。将 parent class 置零会修复吗?

Memory leak in Java Simulation. Will nulling a parent class fix?

我已经为即将举行的机器人竞赛开发了模拟软件。该软件的目的是学习如何使用 NEAT 玩游戏。

要做到这一点,模拟必须 运行 很多很多很多次。但是,我最近才注意到程序中存在严重的内存泄漏。似乎每 10 秒就会分配 1 mb 以上的内存。

我认为内存泄漏存在于我的游戏 class 中,因为这个 class 实际上负责 运行 通过模拟。

我的问题是:

如果我在开始另一个游戏之前将游戏设置为 null 将允许垃圾收集器释放游戏中的每个 child object 还是我也必须将它们设置为 null。

这样做有用吗?

{

    //=-=-=-=-=-=-=-=-=--=-=-=-=-=-=
    Game game = new Game(someParams);

    while(!(game.isFinished()))
    {
        game.run();
        game.draw();
    }

    //do some stuff for NEAT

    //remove the memory
    game = null;
    System.gc();
    //=-=-=-=-=-=-=-=-=-=-=-=-=-

}

在此方法的开头,您将一个全新的实例分配给游戏。最后将其设置为 null 可能会有所帮助,具体取决于您之后的操作。如果这是该方法的结尾,将其设置为 null 将不会有任何改变,因为游戏引用会在之后立即被销毁(就像您已分配 null 一样)。如果你在设置为null后继续用同样的方法做事,可能会有所帮助,但这不是最终的解决方案。

Java 中的内存泄漏通常是因为您忘记释放对对象的引用。例如将它添加到列表中,并且在完成时忘记将其删除。

JDK 为此提供了一些工具:

$ jmap -dump:format=b,live,file=/tmp/dump <pid>
$ jhat /tmp/dump

jhat 创建一个侦听端口 7000 的 HTTP 服务器。使用浏览器打开 http://localhost:7000,在第一页的末尾,您会找到选项 "Show instance counts for all classes (excluding platform)."

单击它,您将看到所有已加载的 classes 的列表,按实例数排序。 classes 中的一两个将具有异常多的实例。单击 "instances",您将获得该 class 的所有实例的列表。

单击其中一个实例,您将看到实际对象,并在 "References to this object" 下显示一个保留对它的引用的对象列表。

某些引用对象将具有对其的有效引用。其他人可能有一个被遗忘的参考。尝试通过检查未释放的对象的多个实例来确定哪个对象(列表、映射、集合等)保留了被遗忘的引用。