当SignalR Hub
变满时,它的大小翻倍,占用内存的两倍,但是如果从中删除了元素,它会自动减小吗?
据我所知,减少List<T>
并不意味着重新定位内存中的所有数据,它只需要从保留内存的末尾删除,但它实际上是否会这样做?
答案 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++;
}