它在.NET众所周知,类型不是垃圾回收,这意味着,如果你与f.ex.玩弄 Reflection.Emit的,你必须要小心卸载的AppDomain等等......至少这就是我用来理解事物是如何工作的。
这使我想知道,如果通用类型是垃圾回收,更精确地说:与创建泛型MakeGenericType
,比方说......例如基于用户输入。 :-)
所以,我构建了以下测试案例:
public interface IRecursiveClass
{
int Calculate();
}
public class RecursiveClass1<T> : IRecursiveClass
where T : IRecursiveClass,new()
{
public int Calculate()
{
return new T().Calculate() + 1;
}
}
public class RecursiveClass2<T> : IRecursiveClass
where T : IRecursiveClass,new()
{
public int Calculate()
{
return new T().Calculate() + 2;
}
}
public class TailClass : IRecursiveClass
{
public int Calculate()
{
return 0;
}
}
class RecursiveGenericsTest
{
public static int CalculateFromUserInput(string str)
{
Type tail = typeof(TailClass);
foreach (char c in str)
{
if (c == 0)
{
tail = typeof(RecursiveClass1<>).MakeGenericType(tail);
}
else
{
tail = typeof(RecursiveClass2<>).MakeGenericType(tail);
}
}
IRecursiveClass cl = (IRecursiveClass)Activator.CreateInstance(tail);
return cl.Calculate();
}
static long MemoryUsage
{
get
{
GC.Collect(GC.MaxGeneration);
GC.WaitForFullGCComplete();
return GC.GetTotalMemory(true);
}
}
static void Main(string[] args)
{
long start = MemoryUsage;
int total = 0;
for (int i = 0; i < 1000000; ++i)
{
StringBuilder sb = new StringBuilder();
int j = i;
for (int k = 0; k < 20; ++k) // fix the recursion depth
{
if ((j & 1) == 1)
{
sb.Append('1');
}
else
{
sb.Append('0');
}
j >>= 1;
}
total += CalculateFromUserInput(sb.ToString());
if ((i % 10000) == 0)
{
Console.WriteLine("Current memory usage @ {0}: {1}",
i, MemoryUsage - start);
}
}
Console.WriteLine("Done and the total is {0}", total);
Console.WriteLine("Current memory usage: {0}", MemoryUsage - start);
Console.ReadLine();
}
}
正如你所看到的,泛型类型定义“可能递归”,与标志着递归结束一个“尾巴”类。 并确保GC.TotalMemoryUsage
没有作弊,我也打开任务管理器。
到现在为止还挺好。 我做下一件事是火灾此兽了,虽然我在等待一个“内存不足” ......我注意到,这是-出乎我的意料- 不消耗随着时间的推移更多的内存。 事实上,它显示的时间内存消耗略有下降。
可有人请解释一下吗? 是通用的类型实际上是由GC收集的? 如果是的话......在那里也Reflection.Emit的情况是垃圾回收?