.net 值类型与引用类型

先说一下内存和堆栈:

当程序运行时,.Net会在两个地方存储程序信息,堆内存和栈内存,它们只是对内存的逻辑分段,在程序运行过程中扮演者不同的角色。

栈内存更多的是负责追踪函数调用,内存堆更多的负责记录数据对象。可以把栈看成是一堆盒子一个压着一个的堆叠在一起,当调用一个函数的时候,会在栈顶堆一个新的盒子,我们只能使用最上面的盒子,当最上面的盒子处理完之后(函数调用完成),我们把它扔掉,然后继续处理当前处于栈顶的盒子。

  • 从结构来说,栈是一种后进先出(LIFO)型结构,只能使用栈顶的数据,将栈顶数据弹出之后,才能使用下面的数据;堆是一种列表类型,可以访问堆中的任何数据 。
  • 从管理方式来说,栈能够对实现对内存的自我管理;堆得内存管理需要通过GC来实现。

下面就说一下,code 中怎么占用内存的,或者说是什么占用了内存?

值类型 是分配在栈上(stack)

public struct ValPoint {
      public int x;
      public void Blank() { }
}
ValPoint vPoint1 = new ValPoint(); 
Console.WriteLine(vPoint1.x); // 输出为0

可能大家以为new 就会分配内存,这里的struct 值类型new的时候是不会分配内存的。他只调用ValPoint 这个结构的默认构造而已。

ValPoint vPoint=new ValPoint(10);

这个时候会是怎么样的呢?

答:这个时候会把10 压入栈中,再通过构造把x 属性赋值。

引用类型 是分配在堆上(heap)

当声明一个引用类型变量,并使用new操作符创建引用类型实例的时候,该引用类型的 变量会被分配到线程栈上,变量保存了位于堆上的引用类型的实例的内存地址。变量本身不包含任何类型所定义的数据。

如果仅仅声明一个变量,但不使用new操作符,由于在堆上还没有创建类型的实例,因此,变量值为null,意思是不指向任何对象(堆上的对象的实例)。对于变量的类型声明,用于限制此变量可以保存的类型实例的地址。

例子:假设有以下对象

public class RefPoint {
        public int x;
        public RefPoint(int x) {this.x = x;}
        public RefPoint() {}
}
RefPoint rPoint1;//这样声明不会分配内存

在线程栈上创建一个不包含任何数据,也不指向任何对象 (不包含内存地址)的变量。

RefPoint rPoint1;//这样声明不会分配内存

rPoint1= new RefPoint(1);//加上这一句就不一样了

在应用程序堆(Heap)上创建一个引用类型(RefPoint)对象的实例,并为它分配内存地址。

自动传递该实例的引用给构造函数。(正因为如此,才可以在构造函数中使用this来 访问这个实例。)

调用该类型的构造函数

返回该实例的引用(内存地址),赋值给rPoint1变量;

这样就完成了实例化,这下我们就知道实例化过程中是怎么占用内存的了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值