此代码分配内存,但永远不会释放内存。如何强制收集内存,GC.Collect()似乎也不起作用。
我已经回顾了许多提出这个问题的帖子,但每个人都回答说垃圾收集器会处理内存,但它永远不会。
var list = new List<string>();
for (var i = 0; i < 10000000; i++)
{
list.Add("really long string..................................................................................................");
}
for (var i = 0; i < 10000000; i++)
{
list[i] = null;
}
list.Clear();
答案 0 :(得分:3)
// Clears the contents of List.
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++;
}
如您所见,数组按原样保持分配状态。这是出于效率原因而完成的。数组已经分配,没有必要让GC收集它,因为它可能会再次需要。
您可以设置Capacity
属性以强制它重新分配新数组。这实际上会添加内存压力(除非你将其设置为0),直到收集到前一个数组。这是code for reference:
// Gets and sets the capacity of this list. The capacity is the size of
// the internal array used to hold items. When set, the internal
// array of the list is reallocated to the given capacity.
//
public int Capacity {
get {
Contract.Ensures(Contract.Result<int>() >= 0);
return _items.Length;
}
set {
if (value < _size) {
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.value, ExceptionResource.ArgumentOutOfRange_SmallCapacity);
}
Contract.EndContractBlock();
if (value != _items.Length) {
if (value > 0) {
T[] newItems = new T[value];
if (_size > 0) {
Array.Copy(_items, 0, newItems, 0, _size);
}
_items = newItems;
}
else {
_items = _emptyArray;
}
}
}
}
至于你的非常长的字符串,它只是对一个实习字符串的引用......无论如何,该列表将存储每个项目8个字节(假设一个64位系统)。
答案 1 :(得分:-2)
如果您明确致电GC.Collect()
,并不意味着它会立即被收集。 GC将决定何时收集......