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

Posted

技术标签:

【中文标题】对象的实例变量存储在 JVM 中的啥位置?【英文标题】:Where are instance variables of an Object stored in the JVM?对象的实例变量存储在 JVM 中的什么位置? 【发布时间】:2014-06-26 08:29:31 【问题描述】:

Java中对象的实例变量是否存储在JVM的堆栈或方法区?

另外,我们是否有多个线程的不同实例变量?

如果存储在方法区,实例变量与静态变量存储有何不同?

【问题讨论】:

实例变量是每个对象一个。静态变量是每个类一个。线程(有点)共享相同的内存 【参考方案1】:

大部分 JVM 实现将内存分为以下几部分:

    方法区 堆栈 堆 电脑寄存器 本机方法堆栈。

让我们只讨论方法区、堆栈和堆。

例如上课

class Lava 
  int i = 5;
  static int j = 10;
  void flow()  //some implementation
 

当这个对象的一个​​实例从一个类 X 中创建时

Lava l = new Lava();

首先,Lava 的 Class 类型,即Lava.class 存储在您的 Method 区域中,其中包含方法、字段和其他引用类型等详细信息。此外,我们示例中的 j 等静态变量也存储在方法区域本身中。

第二个对象熔岩的实例存储在堆区以及它的实例变量,即i.

第三,它的引用,即我们例子中的l存储在Stack area中,它指向在Heap中创建的实例。

【讨论】:

【参考方案2】:

准确来说,

实例变量将存储在堆上。 堆栈上的局部变量(如果变量不是原始变量[引用变量] 引用变量位于堆栈上 和堆上的对象)。只有方法调用和部分结果 将存储在堆栈中,而不是方法本身。 上的静态变量和方法(包括静态和非静态) 方法区。

参考:Head First Java

【讨论】:

【参考方案3】:

Stackheap是操作系统分配给JVM的内存,运行在 system.堆栈是存储方法和局部变量的内存位置。 (变量引用 primitiveobject 引用也存储在堆栈中)。 是存储对象及其实例变量的内存位置。

总结一下:

类对象,包括方法代码和静态字段:堆。 对象,包括实例字段:堆。 局部变量和方法调用:堆栈

另外,我们是否有多个线程的不同实例变量?

每个线程都有一个程序计数器 (PC) 和一个 java 堆栈。 PC 将使用 java 堆栈来存储中间值、动态链接、方法的返回值和调度异常。这用于代替寄存器。

还有关于线程的更多信息,你真的应该阅读这个主题Where is Thread Object created? Stack or Heap?。

如果它存储在方法区域中,实例变量与 静态变量存储?

如上所示,静态字段存储在堆中。另一方面,局部变量存储在堆栈中。

//编辑

根据Bruno Reis和Peter Lawrey的cmets,你还应该阅读逃逸分析

    Wikipedia Virtual Machine Performance Enhancements,Escape Analysis

【讨论】:

这并不完全正确。现代 JVM 更加复杂,并且具有优化算法,可以确定将给定对象在给定情况下存储在 stack 上可能会带来更好的性能(即,对 GC 的压力更小)。例如,google JVM Escape Analysis。在任何情况下,除非你写的是非常底层的东西,否则你不应该关心一些东西是存储在堆上还是栈上。 我并不是说这完全正确。这只是一个非常简单的视图,变量是如何存储在 Java 中的。 @BrunoReis true,但逃逸分析很少导致避免使用堆。 @MatejSpili,您的假设不正确:我没有否决您的回答。答案很好,没有错,对大多数开发人员来说已经足够好了,只是不是 100% 严格正确。 (我也没有投票——对我来说,这是完全中立的!)(看起来你的评论现在已经消失了!) @BrunoReis 在这种情况下,我真的很抱歉 :) 我还编辑了带有逃逸分析链接的答案等等......

以上是关于对象的实例变量存储在 JVM 中的啥位置?的主要内容,如果未能解决你的问题,请参考以下文章

参数变量存储在内存中的啥位置?

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

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

成员变量与局部变量的区别

JVM

java中的作用域有哪些?