我正在为自己正在开发的游戏开发一个决斗系统,这是课程的框架:

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() {..
}


挑战者和被告都将被分配为冠军级别。

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

我从来没有完全理解过这一点,我是否需要将类内的所有内容都设置为null以及Duel currentDuel;中的Champion.class声明,还是只将currentDuel设置为等于null,这将有效地停止引用(我想,这就是我对此感到困惑的地方)。

我不太了解垃圾回收将什么视为“参考”类,即使未从外部类接触到它,设置了Duel#getChallenger()仍会将其视为仍被引用吗?

我想我在入站引用和出站引用之间感到困惑,有人会因为我似乎无法理解rtfm时发生的事情而受到启发。

最佳答案

如何正确设置要由Java垃圾回收器收集的类。


您可能不需要执行任何操作。如果没有其他地方对Duel的引用,则Duel对象本身就有资格进行垃圾回收...并且Duel是引用相关Champion对象的最后一件事(等)那么那些也将有资格进行垃圾收集。

如果Champion通过Duel字段引用currentDuel(听起来确实如此),则如果您单独引用了冠军(例如,某处的冠军列表),则这些冠军将防止Duel被垃圾回收,直到currentDuel设置为其他值。但是,实际上,您应该从逻辑上考虑什么,而不是担心垃圾回收...大概在决斗完成后,将currentDuel设置为null还是有意义的,因为冠军不再与那个决斗作斗争...到那时,他们将不再保持Duel的生命。但是,您几乎不需要更改Duel本身中的任何内容。

如果拥护者本身仍然有资格进行垃圾收集,那么您不必担心DuelChampion之间的引用周期-这不会阻止垃圾收集。

所有这一切的原则是“我是否仍可以通过任何活动线程中的任何代码路径到达相关对象?”的问题。如果不能,则可以进行垃圾收集。如果您可以到达相关对象,则不会对其进行垃圾收集。

09-30 12:16