CLRCore

1.CLR:公共语言运行时,就是IL(中间语言)的运行环境;安装.net Framewrok的时会安装CLR

 

 2.堆栈内存分配: CLR进行内存的分配

值类型分配在栈中,变量和值都是在线程栈中(结构体是输出值类型,结构体默认继承system.valuetype,所以不能继承其他类了,结构体不能有无参构造函数,不能继承或者被继承)

引用类型分布在堆上,变量是存在栈中,值是在堆中

3.string类型

//string字符串内存分配
            {
                string student = "大山";//开辟一块内存,放下"大山”,返回一个引用
                string student2 = student;

                student2 = "App";//改了student2的值,但不是修改内存,string字符串的内存是不可变的,不可变是因为享元,可能是多个变量指向同一个字符串
                                 //字符串变化了,多个变量都会受到影响,还因为堆里面的内存是连续分配的,如果变长度,会导致大量数据的移动
                                 //赋值其实是new string(app) ,重新开辟内存,返回引用
                        //这时 student 的值依然是“大山”;            }
            {
                string student = "大山";
                string student2 = "app";
                student2 = "大山";
                Console.WriteLine(object.ReferenceEquals(student,student2)); //结果输出true,clr内存分配字符串的时候,会查找相同值,有就重用了
            }

4.垃圾回收:

值类型出现在线程栈中,每次调用都有线程栈,用完自己就结束

引用类型出现在堆中,全局就一个堆,空间有限,所以需要进行垃圾回收,堆是连续分配的(数组),

GC发生在new的时候, new一个对象时,会开辟内存,看看空间够不够,不够的话就要GC了,发现内存不够,就去遍历堆中的对象,标记访问不到,然后启动一个线程来清理内存;

移动标记了的对象,其他挪动,然后整齐摆放,所以这个时候全部线程停止,不允许操作内存

但是析构函数 会单独的处理,它会把这些对象放入一个队列单独处理,但是不知道什么时候去调用析构函数,析构函数主要时用来释放非托管资源,是clr自动执行的

静态不会回收:如下所示

class GCDemo
    {
        private static Student _Student = new Student() //静态的不可能被回收,静态持有的引用也不会被回收
        {
            Id = 123,
            Name = "jj"
        };
        public static void Show()
        {
            {
                Student student = _Student;
                Class @class = new Class()
                {
                };
                student.Class = @class;
            }
            {
                GC.Collect();//主动GC ,用于定时任务,执行一次后就不执行了,所以需要手动GC
            }
        }
    }

5.GC的2个优化策略:

一.分级策略:

首次GC前全部对象都是0级  ;

第一次GC后,还保留的对象叫1级;

回收先找0级对象,如果空间还不够,再去找1级对象,这之后还存在的对象就变成2级;

0级不够,1级也不够,2级还不够就内存溢出了

二.大对象策略:

如果大于某个值的对象85K,单独管理,用的时链表,避免频繁的内存移动

6.Dispose(); 只有实现了IDIsposable方法,才能使用using关键字;

在用完对象后,我们主动执行Dispose方法,当时可以使用using的快捷方式

internal class Student:IDisposable
    {
        public int Id { get; internal set; }
        public string Name { get; internal set; }
        public object Class { get; internal set; }

        public virtual void Dispose()//提供主动释放方式
        {
            //通知垃圾回收机制不再调用析构器
            GC.SuppressFinalize(this);
        }

        ~Student()//保证垃圾回收时,一定会把非托管资源释放
        {

        }
    }

 

posted @ 2024-08-25 00:24  你好呀嗯嗯  阅读(33)  评论(0)    收藏  举报