C# 中的堆和栈

本文深入解析了栈和堆两种内存管理方式的区别与联系。详细介绍了栈用于存储值类型和引用类型本身,而堆则用于存储引用类型对象及可空类型。通过具体的代码示例展示了在调用方法和创建对象时,栈和堆是如何分配和管理内存的。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        上存储的有:值类型引用类型本身

        栈内存就像一系列堆得越来越高的箱子。调用方法是,它的每一个参数都被放入一个箱子,并将这个箱子放到栈的最顶部。每个局部变量也同样分配到一个箱子,并同样放到栈的最顶部。方法结束后,它的所有箱子都从栈中移除。
        上存储的有:引用类型的“对象”可空类型

        堆内存则像散布在房间里的一大堆箱子,而不像栈那样每个箱子都严格地堆在另一个箱子上面。每一个箱子都有一个标签,它标记了这个箱子是否正在使用。创建一个新对象时,runtime 会查找一个空箱子,并把它分配给对象。对对象的引用则存储在栈上的一个局部变量中。runtime 将跟踪每个箱子的引用数量(有多个变量引用同一个对象)。一旦最后一个引用消失,runtime 就将箱子标记为“未使用”。将来某个时候,会清除箱子里的东西,使之能被真正重用。

        另外,堆内存是一种有限资源,如果被耗尽,new 操作符将抛出一个 OutOfMemoryException ,对象将创建失败。

        代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace stack_heap
{
    class Program
    {
        static void Main(string[] args)
        {
        }

        void Method(int param)
        {
            Circle c;
            c = new Circle(param);
        }
    }

    class Circle
    { 
        public Circle(int a)
        {           
        }
    }
}
        调用Method 方法时,并给 param 传递实参为 8 后:

1、首先,栈中将分配一小片内存(刚好能存储一个 int),并用值 8 来初始化。

2、在方法内部,还要从栈中分配出另一小片内存,它刚好能够存储一个引用(一个内存地址),只是暂时不进行初始化(它是为Cricle 类型的变量 c 准备的)。

3、接着从堆中分配一个足够大的内存区域来容纳一个 Circle 对象。

        PS:new 关键字执行的操作 --- 它运行 Circle 构造器,将这个原始的堆内存转换成一个 Circle 对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值