对象内存模型

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#对象内存模型的更多相关文章

  1. C++/C#中堆栈、对象内存模型、深浅拷贝、Array.Clone方法

    转载自:http://blog.csdn.net/jarvischu/article/details/6425534 目录 1.      C++/C#中对象内存模型................. ...

  2. C#的对象内存模型

    转载自:http://www.cnblogs.com/alana/archive/2012/07/05/2577893.html C#的对象内存模型: 一.栈内存和堆内存1.栈内存 由编译器自动分配和 ...

  3. C++对象内存模型2 (虚函数,虚指针,虚函数表)

    从例子入手,考察如下带有虚函数的类的对象内存模型: class A { public: virtual void vfunc1(); virtual void vfunc2(); void func1 ...

  4. C++对象内存模型1(堆栈模型)

    对象内存模型 一. 栈(Stack) VS. 堆(heap) 栈 由系统自动管理,以执行函数为单位 空间大小编译时确定(参数+局部变量) 函数执行时,系统自动分配一个stack 函数执行结束时,系统立 ...

  5. 从零开始学C++之虚继承和虚函数对C++对象内存模型造成的影响

    首先重新回顾一下关于类/对象大小的计算原则: 类大小计算遵循结构体对齐原则 第一个数据成员放在offset为0的位置 其它成员对齐至min(sizeof(member),#pragma pack(n) ...

  6. Swift 对象内存模型探究(一)

    本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/zIkB9KnAt1YPWGOOwyqY3Q 作者:王 ...

  7. 对C++对象内存模型造成的影响(类/对象的大小)

    首先重新回顾一下关于类/对象大小的计算原则: 类大小计算遵循结构体对齐原则 第一个数据成员放在offset为0的位置 其它成员对齐至min(sizeof(member),#pragma pack(n) ...

  8. Objective-C类成员变量深度剖析--oc对象内存模型

    目录 Non Fragile ivars 为什么Non Fragile ivars很关键 如何寻址类成员变量 真正的“如何寻址类成员变量” Non Fragile ivars布局调整 为什么Objec ...

  9. C++对象内存模型1(堆栈模型)(转)

    对象内存模型 一. 栈(Stack) VS. 堆(heap) 栈 由系统自动管理,以执行函数为单位 空间大小编译时确定(参数+局部变量) 函数执行时,系统自动分配一个stack 函数执行结束时,系统立 ...

随机推荐

  1. Splay POJ3468(老题新做)

    A Simple Problem with Integers Time Limit:5000MS     Memory Limit:131072KB     64bit IO Format:%I64d ...

  2. Android中ExpandableListView控件基本使用

    本文採用一个Demo来展示Android中ExpandableListView控件的使用,如怎样在组/子ListView中绑定数据源.直接上代码例如以下: 程序结构图: layout文件夹下的 mai ...

  3. Stack的三种含义(转载--阮一峰)

    作者: 阮一峰 学习编程的时候,经常会看到stack这个词,它的中文名字叫做"栈". 理解这个概念,对于理解程序的运行至关重要.容易混淆的是,这个词其实有三种含义,适用于不同的场合 ...

  4. 【IOS学习基础】归档和解档

    一.归档介绍 1.归档是指用某种格式来保存一个或多个对象,以便以后还原这些对象的过程.归档是将数据持久化的一种方式(所谓数据持久化,就是指在IOS开发过程中,将数据保存到本地,能够让程序的运行更加流畅 ...

  5. C#制作简易屏保(转)

    C#制作简易屏保[原创] 原始网址: http://www.cnblogs.com/drizzlecrj/archive/2006/10/06/522182.html 2006-10-06 16:25 ...

  6. hdu2304Electrical Outlets

    Problem Description Roy has just moved into a new apartment. Well, actually the apartment itself is ...

  7. L - 辗转相除法(第二季水)

    Description The least common multiple (LCM) of a set of positive integers is the smallest positive i ...

  8. Java转换

    1.如何将字符串String转化为整数int  int i = Integer.parseInt(str);   int i = Integer.valueOf(my_str).intValue(); ...

  9. 引用JS表单验证大全 以后方便查看用

    1:js 字符串长度限制.判断字符长度 .js限制输入.限制不能输入.textarea 长度限制 2.:js判断汉字.判断是否汉字 .只能输入汉字 3:js判断是否输入英文.只能输入英文 4:js只能 ...

  10. mysql 根据规定的数组进行排序

    最近在开发中遇到一个问题,我要根据一组商品的佣金进行排序和分页,可是佣金并不在商品表中,于是我就只能通过数组的操作把佣金计算出来,然后通过array_multisort()方法进行排序,可是无法做到分 ...