一.概念

  堆栈是什么?

  在说堆栈之前,先说说内存是神马?

  内存:程序在运行的过程,电脑需要不断通过CPU进行计算,这个计算的过程会读取并产生运算的数据,这些数据需要一个存储容器存放。这个容器,这就是内存了。

  我们知道C#是强类型语言,每个变量和常量都有一个类型,即所有的数据都会有一个类型。在.Net中,所有的类型又分为值类型和引用类型。简单介绍一下。

    值类型:使用int,float,struct,enum关键字直接继承自System.ValueType定义的类型。

    引用类型:Class,interface,string,delegate继承自System.Object。

  值类型和引用类型有什么区别呐?

  主要区别在于值类型对象固定大小,引用类型对象可以指向任何类型,无法确定其大小。因此内存区域分为栈和堆。值类型存储在栈上,引用类型存储在堆上。

二.栈和堆

                   

      栈:操作系统会为每条线程分配一定的空间,Windows为1M。在栈上的成员不受GC管理器的控制,直接由操作系统分配。或者理解为存储短期较小数据块,超出作用域,自动释放。

      堆:主要用来存放引用类型对象,不需要我们人工去分配和释放,由GC管理器托管。或者理解为存储长期较大数据块,超出作用域并不会被释放,保持被分配的状态。GC会处理未引用的堆内存。

      不同于值类型直接在栈中存放值,引用类型还需要在栈中存放一个指向堆中对象的值的地址。

      值类型,引用类型区别详见:https://www.cnblogs.com/u3ddjw/p/6756536.html

      值类型和引用类型之间可以互转吗?

         这个需求,是很常见,所以要说一下。答案是肯定的,当然可以,这里就需要提到装箱(值类型===>引用类型),拆箱(引用类型===>值类型)。

          装箱:

              I.分配堆内存

              II.将值类型的实例字段拷贝到新分配的堆内存中

              III.返回托管堆中新分配的对象的地址在栈中。这个地址就是一个指向对象的引用。

          拆箱:

              I.检查对象实例,确保它是给定值类型的一个装箱值。

              II.将该值实例复制到值类型变量中。

        

三.GC垃圾管理器

   ①GC和堆内存联系

    上述说到栈是操作系统实时自动分配释放,不需要我们去管理。堆内存也是由GC控制管理。但是GC并不是实时管理的,是需要通过程序员手动或系统定时触发的。因为GC是一个耗时的操作,可能在有些系统中触发的不合时宜(明显卡顿)。所以,GC也需要优化,需要控制在合事宜的情况触发。比如游戏中我们需要在切换Loading时触发GC,而在游戏战斗中控制不能被触发。

     因此优化GC,就是优化堆内存,就是尽量减少堆内存,及时回收堆内存。

   ②GC是什么?

      GC即(Gabarage Collector,垃圾回收器),归属于CLR(公共语言运行时,可以理解为.Net虚拟机),专门用于回收托管堆内存的

    ③GC如何释放堆内存的?

    GC清理堆时,GC收集器会通过一定的算法清理堆中的对象,并且版本不同算法也不同。标记-压缩算法:通过一个图的数据结构来收集对象的根,这个根就是引用地址。可以理解为指向托管堆的关系线。当触发这个算法时,会检查图中的每个根是否可达,如果可达,则对其标记,然后在堆上找到剩余没有标记的对象进行删除,这样,

那些不再使用的堆中对象就删除了。

    为了优化内存结构,减少在图中搜索的成本,GC机制又为每个托管堆对象定义了一个属性,将每个对象分为三个等级,0代,1代,2代。

每当new一个对象的时候,该对象会被定义为第0代,当GC开始回收的时候,先从第0代开始,在这样一次回收动作之后,0代没有被回收的对象则被定义为第1代,当回收第1代的时候,第1代中没有被清理的对象会被定义为第2代。

    CLR会为0/1/2代选择一个预算的容量,0代通常为256k-4mb预算,1代为512-4m,2代不受限制,最大可扩充至操作系统的整个内存空间。代数越长说明这个对象经历了回收的次数越多,那就意味着该对象是最不容易被清除的。这种分代的思想将对象分割成新老对象,进而配对不同的清除条件,这种巧妙的思想避免了直接清理整个堆(卡顿后果)。   

    

扩展说明:

      比如Unity采用贝姆垃圾回收机制与.Net垃圾回收器相比一直有很大的限制。

        I.贝姆垃圾回收:无分代\并行,执行时所有线程阻塞;每次标记都会访问所有可达的对象(穷举搜索垃圾)。这种方式极有可能在短时间造成帧率下降,影响玩家体验。

        II.分代回收:效率高很多。

        参考:https://1996v.cnblogs.com/p/9037603.html?from=timeline&isappinstalled=0 

C# 通俗说 内存的理解的更多相关文章

  1. 摘:Windows系统内存计数器理解解析_备忘录_51Testing软件测试网...

    [原创]Windows系统内存计数器理解解析 2008-05-13 11:42:23 / 个人分类:性能测试 说明:本文的计数器以Windows2003为准. 序言;F9n)\%V1a6Z C)?ZV ...

  2. 移动端测试===Android内存管理: 理解App的PSS

    Android内存管理: 理解App的PSS 原文链接:http://www.littleeye.co/blog/2013/06/11/android-memory-management-unders ...

  3. 【VS开发】程序员对内存的理解

    程序员对内存的理解 在C和C++语言开发中,指针.内存一直是学习的重点.因为C语言作为一种偏底层的中低级语言,提供了大量的内存直接操作的方法,这一方面使程序的灵活度最大化,同时也为bug埋下很多隐患. ...

  4. UCOS 内存管理理解 创建任务

    OS_MEM   *OSMemCreate (void *addr, INT32U nblks, INT32U blksize, INT8U *err)   { ................... ...

  5. Android Dalvikvm 内存管理理解

    网上非常多文件介绍了 jvm 内存管理的理论,但在 Dalvikvm 中,到底是怎样实现的. 这几天猛看了 Dalvikvm 的源码,说一下我的理解: 在大层面上讲跟理论一样,jvm 把内存分成了一些 ...

  6. C++内存深入理解

    转载地址:http://www.cnblogs.com/DylanWind/archive/2009/01/12/1373919.html 前部分原创,转载请注明出处,谢谢! class Base  ...

  7. Java内存 模型理解

    概述 在正式讲Java内存模型之前,我们先了解一些物理计算机并发问题,然后一点点的引出Java内存模型的由来. 多任务处理在现在计算机操作系统中几乎是一项必备的功能.这不单是因为计算机计算能力强大,更 ...

  8. Java内存虚拟机理解

        对于Java程序员,在虚拟机自动内存管理机制的帮助下,不需要再为每一个操作写配对的释放资源操作,不容易出现内存泄露和内存溢出问题.加深对Java虚拟机的理解,有助于在发现问题时精准定位问题,排 ...

  9. JVM内存简单理解

    1.首先简单说一下CPU与内存之间的关系 CPU运转速度快,磁盘的读写速度远远不及CPU运转速度,所以设计了内存来缓冲CPU等待磁盘读写:随着CPU的发展,内存读写也远远跟不上CPU的读写速度,CPU ...

随机推荐

  1. 通过adb push 从电脑里复制文件到手机里

    在开发中.我们 常常 须要 从 电脑 拷贝 一些 文件 到  自己的 app 目录里. 我之前的 方式 是 将 手机 链接 电脑,然后 从 电脑里 找到 app 文件夹,然后 进行 拷贝. 可是 这种 ...

  2. java错误:无法将Object转换为int类型

    Object value java要想将Object转换为int类型,就必须先将Object转换为String,然后String再转换为int,如下: Integer.parseInt(String. ...

  3. 开发PL/SQL子程序和包及使用PL/SQL编写触发器、在JDBC中应用Oracle

    1.  子程序的各个部分: 声明部分.可执行部分.异常处理部分(可选) 2.子程序的分类: A.  过程 - 执行某些操作 a.  创建过程的语法: CREATE [OR REPLACE]  PROC ...

  4. SmartDispatcher 类

    UI线程中使用 public class SmartDispatcher { public static void BeginInvoke(Action action) { if (Deploymen ...

  5. [App Store Connect帮助]三、管理 App 和版本(1)添加 App 至您的帐户

    在向 App Store Connect 上传您 App 的构建版本之前,您必须先在您的 App Store Connect 帐户内新建一个 App. 如果您想将 iOS App 和 Apple TV ...

  6. SpringBoot整合Mybatis-plus实现增删查改

    今天给大家分享一下SpringBoot整合Mybatis-plus的增删查改案例. pom.xml <?xml version="1.0" encoding="UT ...

  7. Centos7 时间不正确修复

    查看系统支持的时区列表 timedatectl list-timezones 使用 date -R 查看时区是否正确 date -R 修改时区 timedatectl set-timezone Asi ...

  8. 【BZOJ1124】[POI2008]枪战Maf(基环树_构造)

    被教练勒令做题不能看题解后的第一道新题,自行 yy 了好久终于 AC 了(菜啊)--写博客纪念. 题目: BZOJ1124 分析: 考虑每个人向他要打的人连边.根据题意,所有点都有且只有一条出边.那么 ...

  9. semantic、vue 使用分页组件和日历插件

    最近正在试试semantic-ui,结合了vue,这里忍不住吐槽semantic和vue的友好度简直不忍直视,不过既然用了,这里就分享几个用到的插件了 1.分页组件(基于vue) var pageCo ...

  10. 【转】Java 集合系列08之 List总结(LinkedList, ArrayList等使用场景和性能分析)

    概要 前面,我们学完了List的全部内容(ArrayList, LinkedList, Vector, Stack). Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例 Ja ...