类型、变量与对象详解(中)
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出来的对象、字符串、数组 |
浙公网安备 33010602011771号