C# 为什么这个对象没有被垃圾收集
在下面的代码段中,我想知道为什么在函数调用之后没有收集C# 为什么这个对象没有被垃圾收集,c#,garbage-collection,C#,Garbage Collection,在下面的代码段中,我想知道为什么在函数调用之后没有收集testvectors。我看到内存使用率上升到270Mb,然后一直保持不变 此函数直接从Main调用 private static void increaseMemoryUsage() { List<List<float>> testvectors = new List<List<float>>(); int vectorNum = 250 * 250; Random r
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);
}
}
private static void increaseMemoryUsage()
{
List testvectors=新列表();
int vectorNum=250*250;
Random rand=新的Random();
for(int i=0;i
不要混淆垃圾收集和引用计数。当运行时决定释放内存时,并不总是在不再引用时释放内存。引述:
当满足下列条件之一时,会发生垃圾回收
正确:
系统的物理内存不足
托管堆上已分配对象使用的内存
超过可接受的阈值。这意味着
托管堆上已超过可接受的内存使用率。这
阈值在进程运行时不断调整
调用GC.Collect方法。几乎在所有情况下,您都没有
调用此方法,因为垃圾收集器连续运行。
此方法主要用于特殊情况和测试
如果您感兴趣,请阅读以下内容:
GC可以在需要时运行。那可能要晚很多。在最后一次引用消失后,没有义务直接释放一些内存。您的阵列将在下一个Gen2集合中被收集 除非您继续分配内存,否则函数返回后它可能永远不会运行
您可以使用
GC.Collect()
手动触发GC,但通常不建议这样做。最有可能的情况是,您的TestVector被提升到大对象堆(LOH),然后在Gen0收集期间不会收集它
很好的链接。运行此操作时,我观察到相反的情况:
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);
}
}
}
类程序
{
静态void Main(字符串[]参数)
{
增加MemoryUsage();
控制台.WriteLine(“按回车键强制GC”);
Console.ReadLine();
GC.Collect();
Console.ReadLine();
}
私有静态无效增量MemoryUsage()
{
var testvectors=新列表();
const int vectorNum=250*250;
var rand=new Random();
对于(var i=0;i
垃圾收集是不确定的。由GC决定什么时候是做这件事的好时机。尝试在IncreaseMemorySage()方法使用之前和之后添加,并比较数字。定义“永远”,以及如何检查它?您不能仅仅通过查看RAM消耗来了解GC。请尝试调用GC.collect或其他等效程序,并检查发生了什么。为什么需要收集它?请记住,GC尽可能地懒惰,因为收集总是很昂贵的。仅仅因为一件物品是可以收藏的,并不意味着它会被收藏。它将在GC决定需要释放内存时收集,而不是在之前。另外,请查看您创建vec=new List()的代码,您可以用两种不同的方法更正此问题。。在执行testvectors.Add(ver)之后添加一行vec.clear();vec=null;或将创建的vec移除到for循环的外部。。如果您不希望列表调整大小,那么您也可以执行List vec=new List(1000);例如,与列表testvectors相同=新列表(1000);你明白我为什么建议你的衣服的初始尺寸吗List@Johnyy我怀疑如果你稍微用力一点,然后尝试用大量内存来做其他事情,它会的。让GC在它喜欢的时候运行(而不是用GC.Collect()
)强制它)几乎总是正确的做法。当一个对象不再被引用时,系统通常比您更清楚地知道如何以及何时回收材料以获得最佳性能,而您强制它只是导致它自我猜测,在许多情况下运行较慢。必须立即回收对象的情况非常罕见。系统的信息比程序员少。例如,它不知道您刚刚删除了对200MB数据的最后一个引用。因此,在这种情况下,手动调用它可能是合理的。不幸的是,没有什么好方法可以告诉GC您不再需要大量内存,而不强制它运行。大概系统对特定对象的信息较少,但总体上信息更多。如果它知道另一个对200MB数据的引用,那么你所做的就是让这些东西在另一个GC中存活下来(并有可能将其推广到下一代)。所以如果你要强迫它,你最好他妈的确定你是对的。是的,GC.collect确实把它搞定了。但是,不鼓励使用GC.collect。。。没错,你不需要参与GC,这是你问题的答案;一旦引用超出范围,内存就不会被回收。我要说的一点是,对象可用于收集,并且将在CLR认为合适时收集。