如何正确准备垃圾收集类?

Hob*_*ist 1 java garbage-collection

我正在为一个我一直在努力的游戏制作一个决斗系统,这里是这个类的骨架:

public class Duel {

    private Champion challenger;
    private Champion defendant;

    private boolean duelStarted;

    private long timer;

    public Duel(Champion challenger, Champion defendant) {..

    public void tick() {..

    public void declineDuel() {..

    public void endDuel(ResultType resultType, Champion winner, Champion forfeit) {..

    public void declareWinner(Champion player) {..

    public void declareForfeit(Champion player) {..

    private enum ResultType {..

    public Champion getChallenger() {..

    public Champion getDefendant() {..
}
Run Code Online (Sandbox Code Playgroud)

本课程将分配给挑战者和被告的冠军级别.

当决斗结束时(通过调用Duel#declineDuel()或者Duel#endDuel(ResultType, Champion, Champion)由于类似的东西Champion#Disconnect(),有效地,我应该如何正确地设置类以便由Java垃圾收集器收集.

我从来没有完全理解这一点,我是否需要将类中的所有内容设置为null,以及Duel currentDuel;声明Champion.class或者我应该只将currentDuel设置为null,这将有效地停止引用(我会假设,这这是我对这个类实例的困惑.

我不太明白垃圾收集会认为什么是"引用"类,它会Duel#getChallenger()被设置为被引用仍被引用,即使它没有被外部类触及?

我想我在入境和出境参考之间感到困惑,任何人都会关心一些启示,因为我似乎无法理解当我rtfm发生了什么.

Jon*_*eet 8

我应该如何正确地将类设置为由Java垃圾收集器收集.

你可能不需要做任何事情.如果没有Duel来自其他地方的引用,那么Duel对象本身就有资格进行垃圾收集......如果这Duel是引用相关Champion对象(等)的最后一件事,那么那些也将有资格进行垃圾收集.

如果通过一个字段Champion引用(就像它听起来那样)那么如果你有一个单独的引用冠军(例如你有一个冠军名单),那么这些冠军将阻止垃圾收集,直到设置为不同的值.但实际上,你应该考虑逻辑上有用的东西,而不是担心垃圾收集......大概一旦决斗完成,无论如何都设置为null 是有道理的,因为冠军不再与那场决斗作斗争......在那一点上,他们将不再保持活着.尽管如此,你不太可能需要改变任何东西.DuelcurrentDuelDuelcurrentDuelcurrentDuelDuelDuel

如果冠军本身是符合垃圾收集,无论如何,那么你就不需要担心之间的引用的周期DuelChampion-这不会阻止垃圾收集.

所有这一切的原则是"我是否仍然可以通过任何实时线程的任何代码路径到达相关对象?"的问题.如果你不能,那么它将有资格进行垃圾收集.如果您可以到达相关对象,那么它将不会被垃圾收集.

  • @ Christian.tucker:几乎在所有情况下都应该不管它. (2认同)

Pet*_*rey 5

正如Jon Skeet所指出的那样,最好的办法就是当你完成它时你的对象引用超出了范围.这不仅意味着您不需要将其设置为,null而且您的应用程序将以更合理,更易于维护的方式构建.


您只需将对象图的顶部设置为null.一旦一个对象不再强烈可达,就可以清理它,并且可以清除任何指向不可强烈到达的对象.

在上面的情况下,最简单的事情可能是丢弃Duel对象本身,一切都可以清理.

如果您怀疑内存泄漏,可以使用内存分析器查看哪个引用保留在对象上.这告诉您哪个引用保留在对象上.在Java中,高百分比的内存泄漏是由于对象被添加到集合但未从集合中删除.

  • @ Christian.tucker在没有管理内存的系统中,你必须在完成对象后可靠地调用free()/ delete.这有一些好处,但很容易导致错误.C/C++程序中的内存泄漏是在无法回收内存的时候,在Java中这是不可能的,所以我们在Java中给出"内存泄漏"一个不同的含义来引用任何很久之后保留的对象.需要. (2认同)