方法存储在内存中的啥位置?

Posted

技术标签:

【中文标题】方法存储在内存中的啥位置?【英文标题】:Where are methods stored in memory?方法存储在内存中的什么位置? 【发布时间】:2010-11-20 20:27:10 【问题描述】:

我了解到类字段存储在堆中,但是方法存储在哪里?在堆中还是在其他地方?他们是内联的吗?

【问题讨论】:

【参考方案1】:

方法存储在内存中的其他位置。请注意,方法是针对每个类的,而不是针对每个实例的。所以通常情况下,方法的数量不会随着程序的运行时间而改变(有例外)。在传统模型中,方法所在的地方称为“代码段”。在.net 中,这更困难:方法最初存在于程序集中,并被映射到进程内存中。在那里,即时编译器会在本机代码中创建一些方法的第二个副本;这个副本被执行。 JIT 代码可能会在运行时多次创建和删除,因此也可以将其视为“在堆中”。

【讨论】:

我说的不是“课前”,而是“per-class”。方法是每个类的:这意味着每个方法对于该类只存在一次。不同的实例仍然有相同的方法。属性/属性是每个实例的:每个实例都存在一个属性,即不同的实例具有不同的属性值。 @Martin:我对此有一个担忧。我不明白为什么每次执行该方法时 JIT 代码都会创建一个副本。你已经说过方法是 Per-Class 并且我 100% 同意这一点,但我也相信,当一个方法被调用时,它指的是相同的实际方法,没有复制,因为如果有某种复制的东西(那你说)那么方法怎么可能是Per-Class。 如果我有一个包含 10,000 行代码的方法并且我创建了该方法所属类的 1000 个实例,那么该方法中的已编译代码的 1000 个副本是在内存中创建的还是全部1000 个对象共享相同的,无论是在方法的执行还是该对象的初始化? @Hansmukh:我没有说每次执行该方法时 JIT 都会创建一个副本。相反,我说“在运行时多次”,这意味着 JIT 可能会编译该方法一次,然后在一个小时后丢弃它(如果它没有被调用一个小时),然后在两个小时后重新编译它,等等在。至于 1000 个实例:请注意我说“方法是每个类的”;我真的是这个意思。这也适用于 JIT 代码;在任何时间点,任何方法都最多有一个 JIT 版本。 @Zain:为了支持方法的同时(或后续)激活,使用了由“堆栈帧”组成的“调用堆栈”。方法的每次调用都会创建一个新的堆栈帧(在称为“堆栈”的内存区域中),由该方法的所有参数以及任何局部变量组成。不同的对象不会引起问题:“this”只是作为参数0传递。【参考方案2】:

类方法与所有代码一起存储在专门用于存储代码的程序存储器的专用段中。每个方法的代码存储一次。

【讨论】:

以上是关于方法存储在内存中的啥位置?的主要内容,如果未能解决你的问题,请参考以下文章

对象的实例变量存储在 JVM 中的啥位置?

数组存储在内存中的啥位置?

React Native - AsyncStorage 和状态存储在硬件内存中的啥位置?

静态成员存储在内存中的啥位置? C#.Net中的堆栈/堆[重复]

环境变量存储在 Windows 注册表中的啥位置?

常量变量存储在 C 中的啥位置?