美文网首页C语言程序园
C# 内存的理解 通俗说

C# 内存的理解 通俗说

作者: 编程小世界 | 来源:发表于2019-06-22 19:10 被阅读0次

一.概念

堆栈是什么?

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

内存:程序在运行的过程,电脑需要不断通过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.分代回收:效率高很多。

看我主页简介免费C++学习资源,视频教程、职业规划、面试详解、学习路线、开发工具

每晚8点直播讲解C++编程技术。

相关文章

  • C# 内存的理解 通俗说

    一.概念 堆栈是什么? 在说堆栈之前,先说说内存是神马? 内存:程序在运行的过程,电脑需要不断通过CPU进行计算,...

  • 那个小白还没搞懂内存溢出,只能用案例说给他听了

    内存溢出,通俗的理解,就是你要求分配的内存超出了JVM能给你的,JVM不能满足需求,于是产生溢出。为了便于理解,本...

  • jvm2:Java内存溢出

    内存泄露和内存溢出的区别 内存溢出通俗理解就是内存不够了,不能分配足够大的内存。内存泄露就是程序中已动态分配的堆内...

  • 内存管理——分页、分段

    参考 怎样通俗的理解操作系统中内存管理分页和分段?计算机操作系统 - 内存管理

  • 优化

    1.内存溢出和内存泄漏有什么区别?何时会产生内存泄漏?内存优化有哪些方法? 内存溢出通俗理解就是软件(应用)运行需...

  • C语言内存分配-通俗理解

    转载自 https://blog.csdn.net/farsight2009/article/details/53...

  • java中是否会发生内存溢出,怎么解决,举几个内存溢出的例子

    内存溢出(out of memory)通俗理解就是内存不够,通常在运行大型软件或游戏时,软件或游戏所需要的内存远远...

  • android内存泄漏 OOM查找总结

    本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 前言 先通俗理解下内存泄漏,内存溢出,OOM,...

  • 07.Java内存模型

    Java内存模型 内存模型通俗来理解,就是对物理机的内存包括寄存器高速缓存等构成的计算机运算存储体系的一种抽象。屏...

  • JVM之Java垃圾回收机制

    为大家推荐一篇写的通俗易懂的关于Java垃圾回收机制的文章理解Java垃圾回收机制 Java主要把内存分为堆内存和...

网友评论

    本文标题:C# 内存的理解 通俗说

    本文链接:https://www.haomeiwen.com/subject/dlivqctx.html