方法的代码块在执行时是不是存在于堆栈或堆中?
Posted
技术标签:
【中文标题】方法的代码块在执行时是不是存在于堆栈或堆中?【英文标题】:Does the Code Block of a method live in the stack or heap at the moment of execution?方法的代码块在执行时是否存在于堆栈或堆中? 【发布时间】:2015-12-01 14:49:01 【问题描述】:我对学习编程语言比较陌生,我觉得我对面向对象编程语言的理解有 20% 到 25%,更具体地说是 C# 语言。所以我真的在不知道它的答案对我学习语言的过程的实际意义的情况下提出这个问题,但我真的觉得我需要问这个问题。
当一个方法被调用执行时,我知道它的所有局部变量及其参数和返回值实际上都存在于堆栈内存中。而方法本身作为实例化对象或静态类的成员,或作为非静态类的静态成员从堆内存中调用。
现在我的问题是,当方法被调用到堆栈中时,是只有变量和参数将存在于堆栈中,还是整个方法及其所有代码块都将存在于堆栈中?在那一刻(执行)堆栈?
这个查询产生于实例化方法(或静态方法)内代码块的性质的类似比较,当方法被调用和未被调用时,与非静态类的成员,而该类被实例化为一个对象,而不是。
现在,非静态类的成员被认为是一个蓝图,即它们以一种不可接近和非功能性的形式存在(不能调用字段和方法,不能调用字段的值)得到改变,方法不能改变值),但这个蓝图相当可实例化为一个具有其成员的具体功能对象。
现在,如果堆中实例化方法中的代码块只是一个蓝图,当调用该方法时,该蓝图实际上会在堆栈中“实例化”,以执行堆栈中的任务,然后任务完成后从堆栈中删除。在这里,堆栈可以被视为程序实际执行的地方,而另一方面,堆中的所有内容,包括静态类和对象以及堆本身,都将被视为仅仅是存储数据和指令的地方。时不时地借用堆栈,堆栈实际上执行了我们整个程序的任务。
但是,如果堆栈内存实际上不包含正在执行的方法的代码,并且堆栈仅获取方法的局部变量和参数的临时值,而方法本身在堆中并发从其堆位置执行编码指令,仅将值借给进程中的堆栈。这里堆栈看起来只是一个变量的值持有者,而对象和带有方法的静态类是程序在堆本身中的实际执行者,并且具体存在带有代码的实例化方法(或静态方法)并在堆中运行。
第三种可能性是两个内存(堆栈和堆)都不是代码执行的实际位置,而是在处理器本身的某个地方发生数据的执行和更改,堆和堆栈都在在接受、保存和清理数据和指令方面,只是用于不同使用模式的存储位置,仅此而已。
很抱歉这么长的问题,我不知道获得它的答案对我作为一名程序员有多大帮助,但这确实让我头疼了几天,我找不到答案为初学者设计的文本,所以我真的不知所措!
【问题讨论】:
【参考方案1】:方法没有实例化。类被实例化以创建对象。
对象由数据成员和方法组成。只有数据成员被动态分配在进程内存中的某处。所有方法的代码都静态位于称为“代码段”的内存部分中。任何方法的代码都不会被复制。不需要它,因为它是完全恒定的。
堆栈与代码无关。只有局部变量和参数存在于堆栈中。请注意,如果变量/参数的类型是引用,那么只有引用(指针)的值存在于堆栈中,但它指向的实际对象位于其他位置。
一篇介绍 .NET 内存管理基础知识的文章can be found here。
注意:这有点简化了视图,但对于您的知识水平来说是准确的。
【讨论】:
该问题被标记为 C#,这使事情变得复杂,因为 C# 和 javascript 等某些语言可以在运行时在堆上生成代码。 @PeterTorr-MSFT 当然。然而,OP 甚至还没有开始考虑这些概念。【参考方案2】:程序代码在程序的代码区域中。它既不在堆中,也不在堆栈中。它位于程序执行时加载程序设置的内存区域中。
我建议您阅读有关程序链接和加载的更多信息。
【讨论】:
学习一些程序集也会有所帮助。获取堆栈指针、指令指针的句柄,并了解跳转的工作原理确实有助于绘制图片。以上是关于方法的代码块在执行时是不是存在于堆栈或堆中?的主要内容,如果未能解决你的问题,请参考以下文章