聚美联盟网站怎么做,外贸网站推广seo,做二手房网站有哪些,制作器大家都知道.net程序创建对象后没法写代码销毁对象#xff0c;它有它自己的处理机制#xff0c;今天来大概说说它的原理#xff0c;探讨下它是如何管理对象即管理内存的
在程序里使用new 关键字实例化一个对象 如果这个对象类型是引用类型则在堆上分配然后由GC管理
new 操作…大家都知道.net程序创建对象后没法写代码销毁对象它有它自己的处理机制今天来大概说说它的原理探讨下它是如何管理对象即管理内存的
在程序里使用new 关键字实例化一个对象 如果这个对象类型是引用类型则在堆上分配然后由GC管理
new 操作符编译运行时会做4件事
1、计算对象占内存大小包括对象的所有基类定义的所有实例字段需要的字节数以及类型对象指针和同步块索引(这两个额外成员后面章节会详说)
2、从堆上上分配需要大小的字节数的内存内存中所有的字节都会清0
3、初始化对象的类型对象指针和同步块索引
4、调用类型构造器初始化定义的实例字段返回引用地址并维护指针NextObjPtr(当前对象返回的引用地址当前对象占用的字节数)的值
现在对象是创建好了那它在什么时候回收呢
因为GC在回收时有个代的概念总共有3代可以理解成把内存分成3段GC有它的触发条件最常见的触发条件是0代对象内存分配超过预算就会触发GC
0代分配一个新对象超过预算后就会触发一次垃圾回收GC时会暂定该程序进程中的所有线程并遍历该程序堆中的所有对象如果有正在运行字段引用了该对象就在该对象的同步块索引的最后一位标记1然后将0代所有不是1的对象都回收掉(重写析构函数的不会回收掉)
第1次回收前
第0代ABCDE
然后存活下来的对象A B D提升到第1代
第1次回收后
第1代第0代 ABD
0代再次分配一个新对象超过预算后
第2次回收前
第1代第0代 ABDFGHIJ 存活下来的对象F G I 提升到了第一代 对象A D已经没有活动的字段引用但是第1代没有触发回收条件所以A D不会被回收所以无用的老对象可能存活的时间可能比无用的新对象要久
第2次回收后
第1代第0代 ABDFGI 0代再次分配一个新对象超过预算后此时第1代内存分配也超出预算,同时对象G也已经没有活动的字段引用
第3次回收前
第1代第0代 ABDFGIJKLMN 1代存活的提升到了第2代0代存活的提升到了第1代
第3次回收后
第2代第1代第0代 BFIJKLN 除了常见的0代超预算还有以下4种情况会触发GC
1、代码显示调用System.GC的静态Collect方法
2、Windows报告低内存的情况
3、CLR正在卸载AppDomain
4、CLR正在关闭
注意一般小对象会优先分配在0代上如果一个对象超过或等于85000字节会直接分配在第2代上然后从上面的图可以看到每次垃圾回收后对象的位置都在变化所以对象的引用地址在每次垃圾回收后是会变化的如果不希望它的引用地址发生变化可以通过GCHandler设置属性为Pinned,但这样会导致内存碎片。