因此,我尝试使用队列创建对象池以回收它们。在实现它之后,我似乎仍然获得相同级别的内存使用率。我正在努力了解使用queue()还是dequeue()是通过引用还是通过值。
void ClearNodeListandBackupToPool(ref List<Node> nodelist)
{
foreach (var node in nodelist)
{
nodePool.Enqueue(node);
}
nodelist.Clear();
}
Node CreateNewNode(Vector2 tile, Node parent, double gCost, double hCost)
{
if (nodePool.Count > 0)
return nodePool.Dequeue().init(tile, parent, gCost, hCost);
return new Node(tile,parent,gCost,hCost);
}
我希望此方法的内存使用率很低或没有,但它保持不变。谢谢您的帮助! :)
答案 0 :(得分:0)
调用Dequeue
时,返回的值是对返回对象的引用。在解释这意味着什么之前,先说出为什么对您可能无关紧要:
如果您这样做:
var list = new List<Object>();
list.Add(new object());
var o = list[0];
现在有两个引用相同的对象。 list
有一个参考,而o
有另一个参考。如果o
超出范围,但list
没有超出范围,则该对象将不会被垃圾回收,因为仍然存在对该对象的引用。
如果您这样做:
var queue = new Queue<Object>();
queue.Enqueue(new object());
var o = queue.Dequeue();
队列中只有一个对对象的引用。为什么?因为一旦将其从队列中取出,该项目便已从队列中删除,因此队列不再有对其的引用。 o
是唯一的引用,并且如果o
超出范围,则对象将被垃圾回收,因为不再有对其的引用。
对象是通过值还是通过引用返回的问题并不重要。
按值返回引用是什么意思?
在上面的示例中,使用列表,list[0]
返回一个值,该值是对该对象的引用。如果我们这样做:
var list = new List<Object>();
list.Add(new object());
var o = list[0];
o = "x";
... o
现在引用一个字符串,但是列表中的项目未更改。尚未替换为“ x”。这是因为从列表中检索该项目会返回一个值,即对该对象的引用的副本。我们尚未检索到实际参考。因此,o = "x";
替换了列表返回的引用的副本,而不是列表中包含的实际引用。
其他人观察到-我同意-理解行为要比用语言表达要容易得多。这些示例很容易理解,但是对发生的事情的描述却并非如此。
C#7引入了ref returns
。这允许方法通过引用返回对象。这意味着该方法返回其自己的引用。很容易发现,因为在调用方法时会使用ref
关键字,例如ref var object = ref queue.Dequeue()
。 (您不能这样做,因为Dequeue
不使用ref returns
。)
我只包括这一点,因为似乎确实需要回答您的问题。出于实际目的,您可能不关心它,直到需要它为止。我毫不怀疑添加它是有原因的,但是我也没有使用它。