我可以说服Garbage Collection截断列表吗?数组?

时间:2014-01-03 11:00:13

标签: c# arrays list garbage-collection

如果我有一个我要修剪的List以节省内存,我似乎能够设置列表容量,然后等待GC释放内存。当List被提升到下一代时,为它分配的内存似乎是列表容量的函数,而不是最初分配的内存。这样可以明确地保存我的复制,最终意味着总共减少1份。

var x = new List<double>(50000000) { 1, 2, 3 };
//Lots of memory used here
GC.Collect(2);
//Still lots of memory used
x.Capacity = 3;
GC.Collect(2);
//Much less memory now used

是否可以使用Arrays以某种方式做同样的事情?

请注意,我不打算明确强制GC - 这只是为了说明当GC最终发生时,内存被释放。

4 个答案:

答案 0 :(得分:1)

我不敢。阵列本质上是固定大小的。

http://msdn.microsoft.com/en-us/library/9b9dty7d.aspx

具体来说:

  

尺寸的数量和每个尺寸的长度   在创建数组实例时建立。这些值不可能   在实例的生命周期中发生了变化。

但是,您可以通过将数组元素设置为null来释放内存。当然,您可以手动调整数组大小,但这需要您创建另一个数组并将相关元素复制到其中。

答案 1 :(得分:1)

只需使用List<T>的{​​{3}}。

这相当于list.Capacity = list.Count,它分配一个大小为list.Count的新数组,并将所有元素复制到它。

您可以对数组使用相同的策略,但您必须自己编写代码:

int[] arr = new int[50000];

int count = 3;
int[] compact = new int[count];
Array.Copy(arr, compact, count);
arr = null;

答案 2 :(得分:1)

在幕后,x.Capacity = 3;x.TrimExcess()会将包含它们的私有数组中的所有条目复制到一个新的小数组中。随后将收集巨大的阵列。

要为您自己的数组做类似的事情,您可以这样做:

var y = new double[50000000];
//Lots of memory used here
GC.Collect(2);
//Still lots of memory used

Array.Resize(ref y, 3);

GC.Collect(2);
//Much less memory now used

Doc:Array.Resize<T> method

答案 3 :(得分:0)

我认为这相当于你的列表示例

var x = new Double[50000000];
//Lots of memory used here
GC.Collect(2);
//Still lots of memory used
var y = new Double[3];
Array.Copy(x, 0, y, 0, 3);
x = y;
GC.Collect(2);
//Much less memory now used