You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

创建类对象时,类内部值类型的内存分配位置疑问

类内部值类型的内存分配位置:堆,而非栈

这个问题其实是很多刚接触托管语言(比如.NET)的开发者容易搞混的点,我来给你掰扯清楚核心逻辑:

首先得明确栈和堆的基础分工:

  • 栈(stack)主要存放独立的局部值类型变量(比如方法里直接写的int x = 10;)、方法调用的上下文数据,它的内存会随着方法执行完毕自动释放。
  • 堆(heap)用来存放引用类型的完整实例,以及所有依附于这些实例的数据,内存由垃圾回收器(GC)负责管理。

当你实例化一个类对象时,这个对象本身是引用类型,会被完整分配在堆上。而类内部的所有值类型成员,本质上是这个对象的组成部分——就像汽车的轮子属于汽车本身一样,它们会和对象的其他数据(比如引用类型成员的地址)一起,乖乖待在堆里,绝对不会跑到栈上去。

举个直观的代码例子(以C#为例):

public class Phone
{
    // 值类型成员
    public int BatteryPercent;
    public bool IsCharging;
    // 引用类型成员
    public string Brand;
}

public void UsePhone()
{
    // 这里的myPhone是栈上的"引用"(可以理解为一个指向堆的指针)
    Phone myPhone = new Phone();
    // 给值类型成员赋值,本质是修改堆上Phone实例里的数据
    myPhone.BatteryPercent = 80;
}

在这个例子里:

  • myPhone这个变量本身在栈上,但它只是个地址,指向堆上的Phone完整实例。
  • BatteryPercent和IsCharging作为Phone对象的一部分,完全存放在堆上,和Brand的引用地址(同样在堆的对象数据区)挨在一起。

容易踩的误区

别以为所有值类型都在栈!只有独立的局部值类型变量(没有嵌套在引用类型里、没被闭包捕获、不是迭代器变量等特殊情况)才会在栈上。只要值类型是引用类型的成员,哪怕是结构体这种值类型嵌套在类里,整个结构体也会跟着类实例一起待在堆上。

总结一句话:类的实例在堆,它的所有成员——不管是值类型还是引用类型——都跟着实例一起在堆上。栈上只有指向这个堆实例的引用变量(如果是局部变量的话)。

内容的提问来源于stack exchange,提问作者dushi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:14:40