类型、变量与对象详解(中)

1.栈(Stack)

栈中存储:

  • 基本数据类型的值(如int、float、bool等)
  • 引用类型的引用(如对象、字符串、数组的引用/指针)
  • 方法参数
  • 返回地址
  • 方法调用相关的上下文信息(如寄存器,栈帧指针等)

注1:引用类型的实际对象存储在堆,而它们的引用(也就是指向堆的“地址”或“句柄”)存在栈

注2:“返回地址”是指函数调用后,应该返回到的代码位置。当一个函数被调用时,程序需要记住“等函数执行完后,回到哪里继续执行”。这个位置(即调用点的下一条指令地址)就被存在栈中,这样函数执行完毕后,程序才能正确返回继续执行。

 

特点:空间小,速度快,遵循“先进后出”(FILO)原则,系统自动分配和释放。

生命周期:变量离开作用域后自动销毁。

示例:

void Main() {
    int a = 1;
    Person p = new Person();
    Foo(a, p);
}

void Foo(int x, Person y) {
    int b = 2;
    // ...
}
+-------------------------------+
| b = 2                         |  // Foo方法局部变量,执行完毕先出栈
+-------------------------------+
| y = p (对象引用)              |  // Foo方法参数
+-------------------------------+
| x = 1                         |  // Foo方法参数
+-------------------------------+
| 返回地址(Foo返回到Main)     |
+-------------------------------+
| a = 1                         |  // Main局部变量
+-------------------------------+
| p (对象引用)                  |  // Main局部变量
+-------------------------------+
| 返回地址(Main返回到外部)    |
+-------------------------------+

 

2.堆(Heap)

堆(Heap)是什么?

堆(Heap)是程序运行时用来存储动态分配的内存区域,尤其用于存放:

  • class实例(对象)
  • string和数组等引用类型的实际数据

堆是用来干什么的?

堆的作用:

  • 存储在编译时大小不固定、生命周期不确定的数据(如对象、字符串、数组等)。
  • 让多个函数、对象或线程可以共享和访问同一块内存(通过引用)。
  • 支持动态内存分配:你可以在运行时创建任意数量、任意大小的对象。

为什么需要堆?(为什么不用栈存一切?)

  • 栈空间有限,适合短暂、局部的数据(如方法参数、局部变量),但无法满足对象、数组等大内存数据的长期存活需求。
  • 对象的生命周期不局限于方法调用范围。栈上的变量随方法调用结束就被销毁,而堆上的对象只要还有引用指向它,就会一直活着。
  • 灵活性:堆允许程序在运行时根据实际需要分配和释放内存。

堆是怎么样的?(怎么工作)

  • 当你用new关键字创建对象时,系统会在堆上为对象分配一块内存,并返回一个引用(地址)。
  • 这个引用会存储在栈上的变量(如p)中。
  • 当所有持有该引用的变量都离开作用域(或者被赋值为null),对象就变成“不可达对象”,等待GC(垃圾回收器)自动释放内存。
  • 堆内存的分配和回收由CLR(.NET运行时)负责,开发者无需手动释放。
class Person
{
    public string name;
    public int age;
}

void Main()
{
    int x = 10;                          // x是值类型,在栈上
    Person p = new Person();             // p是引用类型的引用,在栈上,实际对象在堆上
    p.name = "Tom";                      // name是引用类型,实际字符串"Tom"在堆上
    p.age = 20;                          // age是值类型,存在Person对象的堆内存块里
}
栈(Stack)                  堆(Heap)                         堆(Heap)
+-----------------+          +-----------------------+           +-----------------+
| Person p ------ |--------> |   Person 对象         |           |   "Tom"         |
+-----------------+          |   name ------+--------|---------> |                 |
| int x = 10      |          |              |        |           +-----------------+
+-----------------+          |   age: 20    |        |
| ...             |          +--------------+        |
+-----------------+                                 |
                                                  +---------------------+
                                                  |   其它对象/字符串    |
                                                  +---------------------+

 

3.栈和堆的关系

  栈(Stack) 堆(Heap)
作用 局部变量、参数、返回地址 对象、数组、字符串等引用类型
生命周期 随作用域结束自动销毁 有引用时一直存在,GC回收
分配速度
管理 系统自动 GC自动回收,需引用计数等
典型用途 基本类型、引用变量 new出来的对象、字符串、数组

 

posted @ 2025-08-04 01:17  没有伞的孩子_97  阅读(15)  评论(0)    收藏  举报