如果删除元素,列表<t>将缩小大小

时间:2016-09-13 18:03:34

标签: c# list

SignalR Hub变满时,它的大小翻倍,占用内存的两倍,但是如果从中删除了元素,它会自动减小吗?

据我所知,减少List<T>并不意味着重新定位内存中的所有数据,它只需要从保留内存的末尾删除,但它实际上是否会这样做?

3 个答案:

答案 0 :(得分:27)

不,List不会降低容量,除非您通过设置该属性或使用TrimExcess自行降低容量,除非您调用Clear并且它可以删除缓冲区完全。

当然,这只是当前的实现,而且它是一个实现细节,所以你不能依赖而不缩小支持数组。

答案 1 :(得分:8)

不,List<T>自动回收当前实施的任何空间,并且此实施不太可能很快改变。

但这只是故事的一部分。请注意,一般来说,List<T>只会将引用存储到您的商品中。如果您有一个包含许多对象的大型列表,并且您删除了其中一半,以便不再使用已删除的对象,那么非常接近您列表的一半内存 将被回收GC收集这些对象。

另外,我的理解是当前实现将压缩剩余的项目,这样当列表再次增长时,它会重新使用分配给当前数组的内存中的点。在内部列出。

最后,有办法手动回收空间......但要谨慎使用它们。大多数时候,GC最了解。调用TrimExcess()是因为您刚从大型列表中删除了少量项目,这通常会对您的应用程序造成净损失。

答案 2 :(得分:6)

reference source,我们可以看到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++;
}

似乎没有任何调整基础数组_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++;
}