在下面的代码段中,我想知道为什么函数调用后没有收集testvectors
。我看到内存使用量高达270Mb,然后永远呆在那里。
此功能直接从Main。
调用private static void increaseMemoryUsage()
{
List<List<float>> testvectors = new List<List<float>>();
int vectorNum = 250 * 250;
Random rand = new Random();
for (int i = 0; i < vectorNum; i++)
{
List<Single> vec = new List<Single>();
for (int j = 0; j < 1000; j++)
{
vec.Add((Single)rand.NextDouble());
}
testvectors.Add(vec);
}
}
答案 0 :(得分:9)
不要将垃圾收集与引用计数混淆。运行时决定释放内存,而不是总是在不再引用内存时释放内存。引用:
当满足下列条件之一时,就会发生垃圾收集 真:
系统物理内存较低。
托管堆上已分配对象使用的内存 超过可接受的门槛。这意味着一个门槛 托管堆上已超出可接受的内存使用量。这个 随着过程的进行,阈值会不断调整。
调用GC.Collect方法。在几乎所有情况下,你都没有 调用此方法,因为垃圾收集器连续运行。 此方法主要用于独特的情况和测试。
如果您有兴趣,请阅读此内容:
答案 1 :(得分:5)
GC可以在需要时运行。这可能会晚得多。在最后一次引用消失后,没有义务直接释放一些内存。您的阵列将在下一代Gen2集合中收集。
除非你继续分配内存,否则在函数返回后它可能永远不会运行。
您可以使用GC.Collect()
手动触发GC,但通常不鼓励这样做。
答案 2 :(得分:3)
当我跑这个时,我观察到相反的情况:
class Program
{
static void Main(string[] args)
{
increaseMemoryUsage();
Console.WriteLine("Hit enter to force GC");
Console.ReadLine();
GC.Collect();
Console.ReadLine();
}
private static void increaseMemoryUsage()
{
var testvectors = new List<List<float>>();
const int vectorNum = 250 * 250;
var rand = new Random();
for (var i = 0; i < vectorNum; i++)
{
var vec = new List<Single>();
for (var j = 0; j < 1000; j++)
vec.Add((Single)rand.NextDouble());
testvectors.Add(vec);
}
}
}
答案 3 :(得分:0)
最有可能的是,您的测试向量会被提升为大对象堆(LOH),然后在Gen0集合期间不会收集它。
良好的链接here。
答案 4 :(得分:0)
垃圾收集是不确定的。由GC决定何时是一个好时机。
答案 5 :(得分:0)
尝试在increaseMemoryUsage()方法使用之前和之后添加GC.GetTotalMemory(true)并比较数字。