我们都知道值类型放在栈上,引用类型放在堆上。同时c#是面向对象语言,倡导切皆对象。就算是入口函数Main也是放在类中的,类又是引用类型。那么是否是所有的对象(值类型、引用类型)都是放在堆上的?
内存是一个两个区域(栈、堆)分明
还是说是一个堆中包栈堆的无限循环模式呢?,如果是这种,那么说的装箱问题如何成立呢,因为栈本身就是堆的一部分。
豆子不多,还请各位大神解惑
简单来说堆只是一块内存.栈是则是代码执行的空间.栈空间是在编译时就已经决定有多大的.堆空间是在运行时动态变化的.
也就是说你在代码里int a=1;
编译器知道代码执行到这里的时候会需要一个int变量的空间.所以在程序初始化.代码还没执行时.就已经分出了一块空间给他.
我不明白的是 入口函数在类中,类属于引用类型那么必然再堆上了,那么就算是main函数的类(Program)中定义的字段int a=1也在堆上了,还是说编译的时候会把所有的类都整理一遍,把所有的类中的值类型都放到堆上去,这样说不通把,因为要动态创建类型,编译时候、甚至运行的时候都不知道下一步会有多少个值类型变量产生
你的误区在于不理解代码执行的位置.
代码不是在对象里执行的.代码是有一个单独的区域.在你看来是 object.方法() 这样调用代码.
但实际上是 方法(object) 这样的.你可以理解成所有代码都是静态的.
然后:是先有的栈.系统再在栈上分配空间.并运行代码.分配的栈空间是用来给代码用的.
哈哈哈哈.你的名字是敏感词不让发.@dudu
@吴瑞祥: 我有点明白你的意思了,是不是这样呢:class person{int a},内存中并不是像我们写的代码一样在嵌套执行,而是有另一种机制解析。是不是需要看编译原理才能全部搞清楚?
@吴瑞祥: 哪来的敏感词。。。
是的.你需要学编译原理.我是和我邻居家的孩子聊天的时候他告诉我的.
函数的调用和返回是一个压栈.弹栈的操作.这些只要有个基本概念就行.不需要深究.
如果你想对内存管理有深入了解.就把C程序设计重新认真看一遍.
带你名字的时候就会.
先弄清楚托管堆和堆栈的区别
堆、栈是两块区域。
1.类的成员 字段(静态 、实例)、方法(静态、实例)都分配在堆上。
2.类方法中的局部变量,值类型在栈上,引用类型 同上第1点
字段是值类型呢?也在堆上?
字段是值类型在堆上,字段是引用类型 参考 1、2点。
不多说内存管理了,可能过长。
说说低级语言动态内存分配(反之静态,这种不怎么提),查找栈上的变量自不必说当前上下文是直接可预测的(因为这本身就是次序的),但堆上的我们得到的是什么——指针(或者引用),它不是次序的,是散列随机性的。
如果按照堆为根(后面的说法) ——那么肯定就没有内存泄漏一说了。高级语言(虚拟机类)没有内存泄漏并不是因为堆得的作用域,而还是根据栈的作用域,只是为每个引用做了引用计数,比如变量a=new Form,static b = a;技术为2,假设a作用域过了 Form仍然在堆上,它很明显没有受到a作用域影响,直到b作用域过了计数被置为0了,才发生内存释放(虚拟机当然释放还有代的过程)。
其实是堆为根还是栈为根,你看函数就清楚了(一进去就是main嘛)。
这种问题也不必过于纠结 —— 因为内存管理的设计不是恒定的,上面的举例也只是win的写照,比如没有操作系统的时候,没有内存管理的时候,那就是根据自己的需求快速定制的结构。
但凡靠谱的程序有个通行的做法——往往对象数量>1,就需要进行管理(如内存、窗口、设备...),你根据适当的场景(参数、要解决的问题,比如Android的窗口和WinForm窗口要解决的问题区别比较大)分析思考,然后缩小范围定位之即可测试得到答案。
值类型可以存储在堆和栈上,它是局部变量时存储在栈上,如果值类型是作为类的一个属性,那么就会存储在堆上;
引用类型有两块内存,一块存储引用地址(栈上),一块存储实际的对象(堆上)。
参考:http://www.cnblogs.com/anding/p/5229756.html
1、内存不仅仅只有堆区和栈区
2、堆和栈是程序运行时申请分配的内存空间
3、推荐你去看CLR via C# 里面有一节好像就提到了这个问题
堆和栈的区别,你可以这样理解,堆和栈都是内存上的空间,栈是有编译器进行分配,堆是有开发人员编写的程序分配,堆上存储的是实际值,但是堆上实际值的引用地址是存在栈上记录的,查找堆上的值是先通过栈上引用的内存地址来进行实际的值使用,这也就是引用类型,而栈上的值是没有地址引用,是直接储存的实际的值,这也就是值类型的存储,这是堆栈在存储上的区别,它们代表的是不同的数据结构,你所谓的拆箱装箱,通过上面不同的存储地方,应该能明白,把堆栈上的数据进行相应的转换的时候是有相应的开销的,因为它们的存储地址发生了改变。纯手打,望采纳!
还是没多明白,可能功底不够吧
先扔个示例代码,var person = new Person(); person.age = 10;
按照你的意思 age是存在堆中的栈吗?
不对的,age仍在栈上。这个要代码的执行说起,person|point压入栈,person对应内存压人堆。person.age =10,二级指针person.age 在栈上的值=10;运算过程是在栈上的。所以每个线程有一个自己的独立栈,用于保存运算过程的状态参数等。