当a List<T>变满时,它的大小增加一倍,占用内存的两倍,但如果从中删除元素,它会自动减小吗?
据我所知,减少Capacity并不意味着重新定位内存中的所有数据,它只需要从保留内存的末尾删除,但它实际上是否会这样做?
Ser*_*rvy 27
不,List除非您通过设置该属性或使用显式降低容量,否则不会降低容量,除非TrimExcess您调用Clear它并且它可以完全删除缓冲区.
当然,这只是当前的实现,它是一个实现细节,所以你不能依赖它而不缩小后备阵列.
不,List<T>会不会自动回收任何作为目前实施的空间,这是不太可能实施这一项目很快改变.
但那只是故事的一部分.请记住,一般来说,List<T>只存储对您商品的引用.如果您有一个包含许多对象的大型列表,并且您删除了其中一半,以便不再使用已删除的对象,那么当GC收集这些对象时,将会回收非常接近列表一半内存的内容 .
另外,我的理解是当前的实现将压缩剩余的项目,这样当列表再次增长时,它会重新使用为内部列表使用的当前数组分配的内存中的点.
最后,有办法手动回收空间......但要谨慎使用它们.大多数时候,GC最了解.调用TrimExcess()是因为您刚刚从大型列表中删除了少量项目,这通常是您的应用程序的净损失.
从参考源,我们可以看到该Remove方法调用RemoveAt方法,该方法实现如下:
public void RemoveAt(int index) {
if ((uint)index >= (uint)_size) {
ThrowHelper.ThrowArgumentOutOfRangeException();
}
Contract.EndContractBlock();
_size--;
if (index < _size) {
Array.Copy(_items, index + 1, _items, index, _size - index);
}
_items[_size] = default(T);
_version++;
}
Run Code Online (Sandbox Code Playgroud)
似乎没有任何调整基础数组的大小_items.它仅将索引处的项设置为默认值.
基本上没有.
另请注意,该Clear方法也不会调整数组的大小.它调用Array.Clear将基础数组中的所有项设置为默认值.
public void Clear() {
if (_size > 0)
{
Array.Clear(_items, 0, _size); // Don't need to doc this but we clear the elements so that the gc can reclaim the references.
_size = 0;
}
_version++;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4286 次 |
| 最近记录: |