• 如何使用C#代码证明大对象一开始就会分配在2代堆中?


    大对象指的是大于等于 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 开始的时候是如下图分配内存的

  • 相关阅读:
    Spring基础问答--来自http://my.oschina.net/u/2260184/blog/540576博客
    一些java异常集
    java汉字乱码解决办法
    oracle数据库-表空间基础语法及举例
    大师传承-java代码编写的30条建议
    oracle的表分区的定义与操作
    数据库备份
    PL/SQL语言编程中异常分类及其处理
    PL/SQL编程基本语法学习
    国药准字和药品本位码
  • 原文地址:https://www.cnblogs.com/Jeffrey-Chou/p/12578096.html
Copyright © 2020-2023  润新知