从 .NET 的 Stack<T> 类中弹出项目会减少内存使用量?
Posted
技术标签:
【中文标题】从 .NET 的 Stack<T> 类中弹出项目会减少内存使用量?【英文标题】:Popping item from .NET's Stack<T> class reduces memory usage? 【发布时间】:2018-03-15 02:21:05 【问题描述】:从 .NET 的 Stack<T>
弹出项目是否会减少该堆栈的内存使用量?
MSDN 说 Stack<T>
是作为一个数组实现的,所以我猜想通过弹出一个项目,只有顶部元素的指针会移动到前一个元素,保持所有元素不变。
有人知道吗?
【问题讨论】:
每次添加/删除元素时不断调整数组大小会不会很昂贵? 当您在自己的应用程序中实际从堆栈中删除项目时发生了什么?内存使用量下降了吗? 不,只有 TrimExcess() 这样做。它有一个好名字。不要经常使用它,它很贵。 据我所知,它不会缩小到更小的尺寸,它只会将指针向后移动(至少在没有 TrimExcess() 的 List看一下源码:https://referencesource.microsoft.com/#System/compmod/system/collections/generic/stack.cs,fd86d7436e55c84b,references
// Pops an item from the top of the stack. If the stack is empty, Pop
// throws an InvalidOperationException.
/// <include file='doc\Stack.uex' path='docs/doc[@for="Stack.Pop"]/*' />
public T Pop()
if (_size == 0)
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EmptyStack);
_version++;
T item = _array[--_size];
_array[_size] = default(T); // Free memory quicker.
return item;
它不会调整数组的大小,但它会将数组中的位置设置为default
,因此,如果它是引用类型,垃圾收集将清理曾经存在的对象,从而释放内存。如果它是一个值类型,它不会有任何区别。
【讨论】:
您在哪里看到数组正在调整大小? 对不起,你是对的,它实际上并没有调整大小。只是_size
的值发生了变化。
可能更“正确”的说法是先前位于数组最后位置的项目将被收集(最终)。值本身不会设置为 default
,而是数组的最后一个(可用)元素。【参考方案2】:
不,堆栈的内存使用将保持不变。但是,如果T
是引用类型并且弹出的元素没有其他实时引用,那么它最终可能会被 GC 收集并且弹出实例的内存将被回收,但这不会以任何方式影响内存使用堆栈本身。
如果T
是一个值类型,那么它根本没有区别,因为任何给定的T
或default(T)
都将具有相同的内存占用。
【讨论】:
以上是关于从 .NET 的 Stack<T> 类中弹出项目会减少内存使用量?的主要内容,如果未能解决你的问题,请参考以下文章