我开发了用于机器人竞赛的模拟软件。该软件的目的是学习如何使用NEAT玩游戏。
要做到这一点,模拟必须运行很多次。但是,我刚刚注意到程序中存在内存泄漏。似乎每隔10秒就会分配1个mb的内存。
我相信内存泄漏在我的Game类中,因为这个类实际上负责运行模拟。
我的问题是:
如果我在开始另一个游戏之前将游戏设置为null将允许垃圾收集器释放游戏中的每个子对象,或者我还必须将它们设置为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();
//=-=-=-=-=-=-=-=-=-=-=-=-=-
}
答案 0 :(得分:0)
在此方法的开头,您可以为游戏分配一个全新的实例。最后将其设置为null可能有所帮助,具体取决于您的操作。如果这是方法的结束,则将其设置为null将不会更改任何内容,因为游戏引用会在之后立即销毁(就像您已指定null)。如果在将其设置为null后继续使用相同的方法执行操作,则可能有所帮助,但这不是最终解决方案。
Java中的内存泄漏通常是因为您忘记释放对象的引用。例如,将它添加到列表中,并在结束时忘记删除它。
JDK为此提供了一些工具:
$ jmap -dump:format=b,live,file=/tmp/dump <pid>
$ jhat /tmp/dump
jhat创建一个侦听端口7000的HTTP服务器。使用浏览器打开http://localhost:7000,在第一页末尾,您将找到“显示所有类的实例计数(不包括平台)”选项。 / p>
单击它,您将看到所有已加载类的列表,按实例数排序。一个或两个类将具有异常高的实例数。单击“实例”,您将获得该类的所有实例的列表。
单击其中一个实例,您将看到实际对象,并在“引用此对象”下的一个对象列表中保留对它的引用。
某些引用对象将具有对它的有效引用。其他人可能有一个被遗忘的参考。尝试通过检查未被释放的对象的几个实例来识别哪个对象(List,Map,Set等),保留一个被遗忘的引用。