• c# -- 内存讲解和类型


     1.栈就是商店,找东西快,但是存储的东西少;堆就是仓库,找东西慢,但是存储的东西多

     栈 --- 先进后出

     

     也是因为这个原因,堆中容易出现内存碎片,导致内存空间的浪费·

     CLR就是C#的系统

    (在C#中,不需要我们关心内存释放的问题,C#的CLR的CG会自动帮我们把堆区中的内存释放)


    类型:

    目前我们接触到的类型主要分为两大类:

    值类型和引用类型(其实引用就是c/c++中的指针)当我们开辟数组/对象的时候都用了new,其实这个new就是在堆区开辟数据的关键词,唯一的不同就是在c#中系统会自动帮我们释放堆区数据,并不需要我们手动释放了

    (补充:如何快速的生成一个类的构造函数呢? --- 点击右键或者在代码的左边选中这个小灯泡

    点开之后就有一个生成类的构造函数的选线,选择之后就会自动帮我们生成当前类的有参构造函数

     1.值类型的数据都会被直接存储在栈区

    2.引用类型的数据:对于字符串类型来说,它需要两段内存:一段用于存储字符串数据(字符串数据是常量,只能读而不可修改,所以它会被存到静态存储区),另一段则是用来存储指向字符串位于静态存储区位置的引用(指针)--- 存放在栈区

    3.对于数组和我们自定义的类型(比如类,要注意的是在c#中,结构体和枚举类型都是值类型)--- 首先要明确的是它们的变量都分为两部分 --- 变量声明和变量定义,对于变量定义它们都是用new关键字在堆区创建内存空间的

    所以它们的变量也需要两端内存 : 一段用于存储数据(存在堆区),一段是指向堆区内存空间的引用(指针)--- 存放在栈区


    1.所谓的引用类型其实就是指针类型,创建一个引用类型变量其实就是在创建一个指针,对引用类型变量的定义其实就是在给指针传地址

    对于字符串变量而言 string name = "sdsd" --- 右边这个字符串的本质就是字符串首字符在堆区中的内存空间的地址

    对于类和数组,所谓的变量定义其实就是在创建指针

    int[ ] a;   类名 a; --- 这都是在创建指针

    int[ ]  a = new int [10] ---- 这就是在传地址,右边的new int [ 10 ] 就是一个地址,通过new关键字在堆区创建好内存空间之后,new就会将所创建的内存空间的地址返回(对于数组而言返回的是首元素的地址)

    引用类型创建的指针都存储在栈区中

    (ps:关于类的初始化还有这种初始化方式,花括号内可直接给成员变量/属性赋值,不同的成员变量/属性之间用逗号隔开,最后花括号外面要加个分号)

    2.

    c#和c++中的new表达式的区别是,c#中的new表达式要求类型后面必须跟(),[]或{}作为自变量列表,而c++则是可有可无 

    一.对于类而言,它能选的有()和{ }:当它选择()时又会有三种情况,如果括号里无参数,则在堆区创建对象的同时会调用无参构造函数,如果有参就调用有参构造函数

    如果选择 { } 的话,括号内可以直接对能访问的成员变量/属性赋值,不同的成员变量属性之间用逗号隔开

    二.对于数组而言,他能选的只有[ ] 和 { },其中[ ]必选

    new int[这里面没数据的时候] 后面必须跟 { } ,{这里面的元素个数}就绝对了堆区数组的元素个数

    new int[这里面有数据的时候],{这个可有可无},如果有的话,{这里面的元素个数必须等于我们设定好数组元素个数}


    2.字符串在内存中的存储:一个字符串常量在静态存储区中只有一块内存

    当有多个字符串类型变量指向同一个字符串的时候,这些字符串变量在栈区中存放的地址都是一样的 --- 因为它们都指向了同一个字符串常量,所以它们都指向了同一块静态存储区中的内存空间

    3.对象在内存中的存储情况

     在这种情况下,c1和c2对象在堆区中各自拥有各自的内存空间,c1和c2的引用也都各自不同(各自指向各自的内存空间)

    在这种情况下,如果我们直接将c1赋值给c2的话,我们只会将c1对应的引用直接赋值给c2的引用,此时二者指向同一个内存空间了 

    给一个引用赋值null,就能得到一个空引用 --- 空引用就是什么内存空间都不指向的引用

     

    (GC如何判断堆区中开辟的一个个内存空间是否需要释放呢?---答案是靠计数器

    堆区中开辟的内存空间每有一个引用指向它的话,它就会有一个计数器参数+1,当计数器参数=0的时候,也就是没有引用指向这快内存空间的时候,GC在检测堆区时就会将其释放掉

    顺便补充一下:在程序结束的时候,无论堆区中的内存空间的计数器无论是否为0都会被释放掉)

     

  • 相关阅读:
    风控数据分析师,有哪四大分析工具必须掌握的?
    java 版本企业招标投标管理系统源码+功能描述+tbms+及时准确+全程电子化
    可靠消息最终一致性分布式事务
    认识C#程序中的异常以及异常处理原则
    PAT 乙级1096大美数
    stable diffusion model训练遇到的问题【No module named ‘triton‘】
    Go WaitGroup 和 Cond 实现原理
    pyltp postagger 运行过程中报错Process finished with exit code -1073740791 (0xC0000409)
    为什么不建议给MySQL设置Null值?《死磕MySQL系列 十八》
    深度学习编译器
  • 原文地址:https://blog.csdn.net/qq_51947882/article/details/126367143