C# 内存的理解 通俗说
一.概念
堆栈是什么?
在说堆栈之前,先说说内存是神马?
内存:程序在运行的过程,电脑需要不断通过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
原文地址:https://www.cnblogs.com/guokun/p/11042903.html
C# 内存的理解 通俗说相关推荐
- jvm大局观之内存管理篇: 理解jvm安全点,写出更高效的代码
jvm大局观之内存管理篇: 理解jvm安全点,写出更高效的代码 - 知乎 前言 本篇是java内存区域管理系列教程之一 - 在得知GC Root的组成之后,如何在垃圾回收发生的时刻,找到GC Root ...
- linux性能评估-内存基础理解篇
1.Linux内存是怎么工作的 1.内存映射: 2.虚拟内存空间分布 3.内存分配与回收 4.如何查看内存使用情况 小结 2.理解内存中的Buffer和Cache? 1.free 数据的来源 2.pr ...
- 对二级指针分配内存及理解
废话不多说,直接上正题 因为二级指针和二维数组具有比较共通的特质,先引用二维数组类比二级指针 int test() {char str[5][50];printf("str[1] = %d\ ...
- 【Rxjava】通俗说Rxjava
如下为Rxjava最基础也是最常见的使用样例: /*** 最基础的使用*/Observable.create(new OnSubscribe<String>() {@Overridepub ...
- 压力测试时CPU、内存—初步理解
主要涉及数据库.应用服务器的性能分析 一. 测试数据 1.并发请求50个,两个Url,相当100并发数 应用服务器一直保持CPU占用率为20%-40% 数据库进程连接数提升20个,增加20左右会话数 ...
- “软盘、硬盘、磁盘和内存”的理解
引言 在买电脑时我们通常要考虑的两个参数,就是内存大小和硬盘大小,一般来说内存越大电脑运行速度会越快,硬盘越大能够存储的文件就越多.这么看来硬盘和内存好像毫无关联,其实不然,不管是内存还是磁盘中的硬盘 ...
- linux 内存屏障,理解内存屏障(一)
作者:新浪微博() 计算机学习微信公众号(jsj_xx) 1 前言 内存屏障是搞软件的需要面对的一个涉及硬件cpu的问题,很多人困惑不解.本文是我们对linux内核内存屏障的理解,参考linux内核( ...
- 面性对象中栈内存和堆内存的理解
栈和堆都是Java用来在RAM(随机只读存储器)中存放数据的地方,Java自动管理栈和堆,程序员不能直接地设置栈和堆. Java堆是运行时数据区,通过new关键字从中分配内存空间,在堆内存中产生的垃圾 ...
- C语言之从内存角度理解不同类型的变量
我们都知道在C语言中不同类型的变量在内存中的存放位置不同的,从内存角度上讲,不同内存块中存放的代码或者变量其属性(主要是作用域.生命周期.链接属性)是不同的. 首先我们介绍一下作用域.生命周期已经链接 ...
最新文章
- 关于 OpenIdConnect 认证启用 HTTPS 回调 RedirectUri 不生效问题
- linux下重启weblogic(关闭和启动)
- red hat enterprise linux 7关闭防火墙的方法
- python读取python源代码文件_python 学习源码练习(2)——简单文件读取
- php 取post原始,PHP 获取POST的最原始数据方法
- 读书笔记《Java开发技术-在架构中体验设计模式和架构之美》
- include指令的局限性
- 小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_6-1.常用的第三方支付和聚合支付介绍...
- Grasshopper 0.9汉化版下载 【Rhino5.0参数化插件】
- VMware 注册码
- Excel VBa 连接Oracle数据库
- 2020年内蒙古自治区第十五届大学生程序设计竞赛榜单
- python三国演义人物出现次数_Python分析《三国演义》人物出场次数,孔明第二,赵云第五...
- 幼儿园计算机网络教室工作计划,幼儿园2017-2018学年游戏教学工作计划
- 简单区分单射、满射与双射
- SQLyog:Error Code : 1583 Incorrect parameters in the call to native function ‘concat‘
- 垃圾邮件识别-朴素贝叶斯算法
- hdu 1284钱币兑换问题
- layui文件上传(头像上传)
- 在Python中一步一步实现Principal Component Analysis(PCA)
热门文章
- 更新!在线状态和用户的共存模式保持一致
- Thinkphp 3.2中控制页面不缓存
- 3月6日云栖精选夜读:如何实现32.5万笔/秒的交易峰值?阿里交易系统TMF2.0技术揭秘...
- TypeError: 'MongoClient' object is not callable
- 基于key/value+Hadoop HDFS 设计的存储系统的shell命令接口
- 嵌入式WiFi芯片价格战已经打响 MCU企业该醒悟了
- Briefly unavailable for scheduled maintenance message after doing automatic upgrade
- 纯IPv6环境App适配的坑
- 介绍一款受欢迎的.NET 开源UI库
- 3月更新来了!Windows 11正式版22000.556发布