(转)c#对象内存模型
对象内存模型
C#的对象内存模型
写这篇博客的主要目的是为了加深自己的理解,如有不对的地方,请各位见谅。
C#的对象内存模型:
一、栈内存和堆内存
1、栈内存
由编译器自动分配和释放,主要用来保存一些局部变量、函数的参数等,例如,int a = 10 ,那么编译器会自动在栈上开辟一块内容用来存储变量a。
2、堆内存
由程序员手动申请和释放,在C++中,通过new关键字申请,编译器不会释放,必须通过delete释放,对于C#,通过new 关键字申请,因为编译器的垃圾回收机制,程序员不需要手动释放内存。例如,我们为类student声明了一个对象zhangsan,student zhangsan = new student(),首先,编译器会分配一块栈上的内存存储变量zhangsan,然后在堆上开辟一块内存来存储student对象,最后把堆上的地址存储到变量zhangsan中,如果我们又创建了一个对象lisi,student lisi= new student(),然后lisi = zhangsan,其实更改的只是存储在栈上的lisi的值,即所指向的对象在堆上的地址,如下图所示:
3、栈内存和堆内存的比较
内存分配
栈:后进先出式,由编译器自动分配相应类型的大小,分配的大小受限于栈的大小;
堆:随意分配,由程序员手动申请指定大小,分配的大小受限于虚拟内存。
效率
栈:高
堆:相对栈低
二、值类型和引用类型
1、值类型
值类型变量存储的是变量的值,直接存储在栈内存中;
2、引用类型
引用类型变量存储的是变量所在的内存的地址,引用类型变量的实际数据存储在堆内存中,变量本身存储在栈内存中,存储的是指向堆的地址,通常是四个字节,保存着一个地址数值。
C#中的值类型:struct,enum(对于int,float类型,都属于struct类型)
引用类型:class,delegate,array,interface
具体如下图所示:
三、深拷贝和浅拷贝
我们在编程中常常会遇到这种问题,我们已经有了一个对象a,并且对象a已经有了一些具体的值,现在我们想创建一个a的副本即对象b,我们希望,操作对象b的同时不改变对象a的值,也就是说对象a和对象b是两个完全独立的对象,这即是深拷贝。深拷贝的概念:源对象与拷贝对象互相独立,其中任何一个对象的改动都不会对另外一个对象造成影响。
当两个对象指向同一个地址时,如果我们改变其中一个对象的值,另一个对象也被相应的改变,这即是浅拷贝。浅拷贝的概念:浅拷贝时两个对象并未完全“分离”,改变顶级对象的内容,不会对另一个对象产生影响,但改变子对象的内容,则两个对象同时被改变。
这种差异的产生,即是取决于拷贝子对象时复制内存还是复制指针。深拷贝为子对象重新分配了一段内存空间,并复制其中的内容;浅拷贝仅仅将指针指向原来的子对象。
一些需要注意的东西
(1):String字符串对象是引用对象,但是很特殊,它表现的如值对象一样,即对它进行赋值,分割,合并,并不是对原有的字符串进行操作,而是返回一个新的字符串对象
(2):Array数组对象是引用对象,在进行赋值的时候,实际上返回的是源对象的另一份引用而已;因此如果要对数组对象进行真正的复制(深拷贝),那么需要新建一份数组对象,然后将源数组的值逐一拷贝到目的对象中
(转)c#对象内存模型的更多相关文章
- C++/C#中堆栈、对象内存模型、深浅拷贝、Array.Clone方法
转载自:http://blog.csdn.net/jarvischu/article/details/6425534 目录 1. C++/C#中对象内存模型................. ...
- C#的对象内存模型
转载自:http://www.cnblogs.com/alana/archive/2012/07/05/2577893.html C#的对象内存模型: 一.栈内存和堆内存1.栈内存 由编译器自动分配和 ...
- C++对象内存模型2 (虚函数,虚指针,虚函数表)
从例子入手,考察如下带有虚函数的类的对象内存模型: class A { public: virtual void vfunc1(); virtual void vfunc2(); void func1 ...
- C++对象内存模型1(堆栈模型)
对象内存模型 一. 栈(Stack) VS. 堆(heap) 栈 由系统自动管理,以执行函数为单位 空间大小编译时确定(参数+局部变量) 函数执行时,系统自动分配一个stack 函数执行结束时,系统立 ...
- 从零开始学C++之虚继承和虚函数对C++对象内存模型造成的影响
首先重新回顾一下关于类/对象大小的计算原则: 类大小计算遵循结构体对齐原则 第一个数据成员放在offset为0的位置 其它成员对齐至min(sizeof(member),#pragma pack(n) ...
- Swift 对象内存模型探究(一)
本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/zIkB9KnAt1YPWGOOwyqY3Q 作者:王 ...
- 对C++对象内存模型造成的影响(类/对象的大小)
首先重新回顾一下关于类/对象大小的计算原则: 类大小计算遵循结构体对齐原则 第一个数据成员放在offset为0的位置 其它成员对齐至min(sizeof(member),#pragma pack(n) ...
- Objective-C类成员变量深度剖析--oc对象内存模型
目录 Non Fragile ivars 为什么Non Fragile ivars很关键 如何寻址类成员变量 真正的“如何寻址类成员变量” Non Fragile ivars布局调整 为什么Objec ...
- C++对象内存模型1(堆栈模型)(转)
对象内存模型 一. 栈(Stack) VS. 堆(heap) 栈 由系统自动管理,以执行函数为单位 空间大小编译时确定(参数+局部变量) 函数执行时,系统自动分配一个stack 函数执行结束时,系统立 ...
随机推荐
- IOS百度地图语音导航
VoiceNavigationViewController.m * 客户端需安装百度导航地图 #import "VoiceNavigationViewController.h" # ...
- 解决安装Visual Studio 2012后SQL Server 2008 远程过程调用失败的问题
安装了Visual Studio 2012后,打开SQL Server 2008配置管理器,发现了一个问题.如下图 解决办法:
- ASP.NET通用权限组件实现一
沙发(SF)通用权限验证组件 开篇 上一篇提到了通用权限的设计思路,根据设计思路一步一步的来实现一个相对通用的权限验证组件.在VS2010下用C#语言基于.net framework2.0框架实现具体 ...
- 【IOS学习基础】归档和解档
一.归档介绍 1.归档是指用某种格式来保存一个或多个对象,以便以后还原这些对象的过程.归档是将数据持久化的一种方式(所谓数据持久化,就是指在IOS开发过程中,将数据保存到本地,能够让程序的运行更加流畅 ...
- .NET c# 串口通信
这段时间做了一个和硬件设备通信的小项目,涉及到扫描头.输送线.称重机.贴标机等硬件.和各设备之间通信使用的是串口或网络(Socket)的方式.扫描头和贴标机使用的网络通信,输送线和称重机使用的是串口通 ...
- printf--动态指定输出格式长度
char a1[] = {'A', 'B', 'C'}; char a2[] = "world"; printf(, a1, , a2); printf("[%.*s][ ...
- codeforces 519A. A and B and Chess,
A. A and B and Chess time limit per test 1 second memory limit per test 256 megabytes input standard ...
- SQL Server 性能篇- 碎片
本文分为两个问题: 第一,碎片是什么:第二,碎片怎么处理: 现在,来找解决这两个问题: 一.碎片是什么 说到碎片,就要提到索引了,索引用着挺爽的啊!是的,一旦索引建立,我们搜索数据的效率就提高了:然 ...
- Oracle EBS-SQL (OM-4):检查发运网络.sql
select msn.FROM_ORGANIZATION_CODE 开始库存组织, msn.FROM_ORGANIZATION_NAME 开始库存名称, ...
- activity 的返回按钮
http://www.2cto.com/kf/201210/160251.html 连续点击两次程序就退出程序,这是一个很有趣的程序功能,下来介绍一下我的实现方式(欢迎大家拍砖指点): 1.在Ac ...