我读过这篇文章:https://devblogs.microsoft.com/oldnewthing/20100810-00/?p=13193 https://devblogs.microsoft.com/oldnewthing/20100810-00/?p=13193老实说我不明白每一个细节。据我在下面的代码中的理解c
即使我不设置也应该收集c
to null
。另一件事是分配发生在foreach
似乎只要我们在同一个函数的作用域内就不会被释放。 (参见下面的示例)
class Program
{
public class SomeClass
{
public byte[] X;
public SomeClass()
{
X = new byte[1024 * 1024 * 100];
X[155] = 10;
}
}
static void Main()
{
Console.WriteLine("Memory: " + GC.GetTotalMemory(false));
SomeClass c;
c = new SomeClass();
Console.WriteLine("Memory: " + GC.GetTotalMemory(false));
GC.Collect();
Console.WriteLine("Memory: " + GC.GetTotalMemory(true));
Console.ReadKey();
/* Output:
*
* Memory: 186836
* Memory: 105044468
* Memory: 104963676
*/
}
}
EDIT第一个示例的解决方案:调试模式(不在调试器中运行,甚至在编译模式中运行)。如果我使用 Release 它将按预期工作:c
即使没有设置也会收集null
。对于第二个示例,同样适用。
第二个例子
static void Main(string[] args)
{
Console.WriteLine("Startup Memory: " + GC.GetTotalMemory(false));
var obj = BOObject.Get();
Console.WriteLine("Fetched Object: " + GC.GetTotalMemory(false));
GC.Collect();
Console.WriteLine("Fetched Object (Collected): " + GC.GetTotalMemory(false));
foreach (var node in obj.Traverse())
{
string name = node.Name;
}
Console.WriteLine("Traversed: " + GC.GetTotalMemory(false));
GC.Collect();
Console.WriteLine("Traversed (collected): " + GC.GetTotalMemory(false));
obj = null;
GC.Collect();
Console.WriteLine("collected: " + GC.GetTotalMemory(true));
Console.Read();
}
Output:
Startup Memory: 193060
Fetched: 8972464
Fetched (Collected): 5594308
Traversed: 272553096
Traversed (collected): 269564660
collected: 269564048
如果我把foreach
在另一个函数中循环并调用这个函数,之后使用的内存.Collect
被调用的次数约为 5800000。那么为什么当我有foreach
在同一个函数中循环?
Raymond 文章的评论和 Yun Jin 的 MSDN 文章中提到here http://blogs.msdn.com/b/yunjin/archive/2005/05/15/417569.aspx that
事实上,对于可调试代码,JIT
将每个变量的生命周期延长至
函数结束。
因此,正如您所发现的那样,您的集合不会在调试模式下收集,以及为什么它将在发布模式下收集。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)