大对象指的是大于等于 85000 字节的对象。我这边使用 GC 类的静态方法进行获得,暂时还没有想到别的方法来获得,也没有想到能确切获得这个对象是不是大对象的方法。
byte[] bigArray = new byte[85000]; Console.WriteLine(GC.GetGeneration(bigArray));
输出结果:
可以看到,使用 GC.GetGeneration(Object) 只能看到这个对象处于 2 代中,但是如果要看是不是真的是大对象,可以使用一些性能调试软件看出。这里使用 CLRProfiler 进行查看,如下图:
我们分配的 Byte[] 是被分配在 LOH 中的。这说明,确实大小等于 85000 字节的对象直接被分配到了大对象堆中。
最后,要注意的是,不能使用如下代码进行测试:
大对象声明:
public class BigObject { public byte[] bigArray = new byte[85000]; ~BigObject() { Console.WriteLine("BigObject Collected!"); } }
上端调用:
BigObject bigObj = new BigObject(); bigObj = null; Console.WriteLine("0代、1代回收"); GC.Collect(1); Console.ReadKey();
输出结果:
可以看到,这边这个 BigObject 被回收了,即使是将 GC.Collect 设置为 0 代也是一样回收。这个错误是一个误区,BigObject 的回收不会和它其中的 85000 字节的 bigArray 一起被回收,而是在 BigObject 被回收后 bigArray 还是存在于大对象堆中。其实 BigObject 开始的时候是如下图分配内存的: