【问题标题】:java queue not deallocatingjava队列未解除分配
【发布时间】:2014-04-28 00:44:56
【问题描述】:

我调用下面的方法,每次“finishedRacers”都有相同的对象。我尝试放置一个 .clear(),并使用 new 为其分配新内存,但每次我重新输入该方法时,它都会返回相同的对象。即使在我尝试重新分配并清除它之后,为什么finishedRacers 仍然持有对象有什么想法吗?

@Override
public Queue<Racer> stopThenResetEvent(){
    Queue<Racer> q = new LinkedList<Racer>();
    while(!finishedRacers.isEmpty()) q.add(finishedRacers.poll());
    return q;
}

不确定这是否重要,但该类涉及继承,并且在 this 扩展的抽象类中声明了 finishedRacers 队列。抽象类继承自接口。

编辑:

finishedRacers 的声明方式与 q 相同,它是一个使用 LinkedList 实现的队列。队列在此类扩展的抽象类中声明。它去 IEvent (Interface) --> Event (Abstract, 其中队列被声明) --> GroupEvent (这个被覆盖的方法被调用的类)。我调用此方法的目的是清除 finishedRacers 队列并返回其中保存的对象。

当我多次调用此方法时,不更改事件状态(添加新赛车手、开始比赛等),但再次调用此方法时,它将不断返回相同的赛车手队列。但我的期望是,一旦调用它,除非将更多的赛车手添加到 finishedRacers 队列中,否则它应该是一个空队列。

【问题讨论】:

  • finishedRacers 到底是什么类型?能否请您发布一个更完整的示例,以便我们重现该问题。
  • 这段代码与提到的问题无关,麻烦换个地方试试。在涉及finishedRecords 的地方添加更多代码。
  • 您可以考虑将Queue#poll() 更改为remove(),这样如果队列为空,您将得到一个异常(而不是空值)。您可能还需要synchronize (finishedRacers);是什么让您认为这是您的错误所在?
  • 这个方法的目的是什么?它在语义上与 return finishedRacers; 相同,或者使用 finishedRacers 或其访问器方法而不是根本调用此方法。
  • aleks:此代码使用的唯一上下文是当我直接调用它以将完成的Racers 添加到另一个类中的队列并打印出结果时。我调试了代码,并且在单步执行时唯一的异常是队列将对象保留在其中,但是 poll() 我认为应该删除它们,我还尝试了 clear() 并分配了一个新队列,但队列总是有再次完成赛车手。在我多次调用此函数之间没有运行任何代码行

标签: java memory-management methods queue


【解决方案1】:

在这么小的代码中很难找到错误。

finishedRacers 使用下一个代码 sn-p。使用您在代码中使用的方法扩展下面的列表,并使用 BugFinderList

实例化 finishedRacers

它将帮助您找到错误。


public class BugFinderList extends LinkedList {

    @Override
    public synchronized boolean add(Object o) {
        boolean result = super.add(o);
        System.out.println("[Add] List size is ["+size()+"]");
        return result;
    }

    @Override
    public synchronized void clear() {
        super.clear();
        System.out.println("[Clear] List size is ["+size()+"]");
    }

    @Override
    public synchronized Object poll() {
        Object result = super.poll();
        System.out.println("[Poll] List size is ["+size()+"]");
        return result;
    }
}

【讨论】:

  • finishedRacers 不是一个类,它是一个 Queue...racers 只是一个保存信息的类,没什么特别的。我没有实现自己的队列类或任何东西
  • 用 BugFinderList 结束检查日志替换 finishedRacers 声明。 finishedRacers = new BugFinderList();
  • BugFinderList 的输出仅在方法第一次运行时输出。有任何想法吗?编辑:当我调试并单步执行时,它会在多次调用我的方法时进入 LinkedList.class(超类)而不是 BugFinderList 代码。第一次进入 BugFinderList。
  • 编辑:在finishedRacers 上执行新操作时我没有使用BugFinderList,现在我每次运行该方法时都会继续打印出相同的内容。它说在我离开之前我有零个元素,当我重新输入它时,它的备份最多为 3。
  • 文字不像代码那么“丰富”。请提供完成的代码示例,这会导致麻烦。它肯定会加速问题的解决。
【解决方案2】:

问题出在打印出赛车手的代码中。这是问题代码:

q = currentEvent.getCurrentFinished();
if(q.isEmpty()) q.addAll(finishedRacers.get(run));

直到进行研究,我才知道在返回时调用 addAll 方法也会将其添加到引用队列中,我认为更改将是本地的。使用此代码修复它:

Queue<Racer> q1 = currentEvent.getCurrentFinished();
if(q1.isEmpty()) q.addAll(finishedRacers.get(run));
else q.addAll(q1);

这样我永远不会在返回的队列上调用 addAll。

【讨论】:

    猜你喜欢
    • 2018-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-29
    • 1970-01-01
    相关资源
    最近更新 更多