实例变量的引用存储在哪里?

huangapple go评论72阅读模式
英文:

Where are references of instance variables stored?

问题

我知道原始数据类型和对象引用(用于方法内部使用的对象)被存储在栈帧上,实际对象则存储在堆上。但我对于实例变量(属于引用类型)的引用存储位置不是很清楚。

请有人解释一下这些实例变量的引用存储在哪里,以及如果一个方法想要使用任何实例变量,具体是如何运作的?

英文:

I know that the primitives and object references(for objects used inside a method) are stored on the stack frame and the actual objects are stored on heap. But I am not very clear on where the references to instance variables(which are reference type) are stored.

Can someone please explain where are those references(for instance variables) stored and if a methods wants to use any of the instance variables, then how exactly it works?

答案1

得分: 3

所有实例变量都存储在对象内部,位于堆上。在此过程中,引用变量和原始类型变量之间没有区别。变量的“值”是一个“引用”或“指针”,可以是特殊的 null 值,或者它指向一个对象,通过一种实现特定的机制(OpenJDK HotSpot JVM 称之为“oop”,据说来源于“ordinary object pointer”)。

关于对象的内存布局,您可以阅读更多信息:

另一个问题是实例变量在对象内部的存储方式:它们的排列顺序是怎样的,或者它们是否被紧密地存储。实例变量很可能不是按照源代码顺序存储的,但这方面的细节在不同的JVM实现和版本之间有很大的变化。

OpenJDK现在包含了一个工具,您可以使用它来检查对象的布局:http://openjdk.java.net/projects/code-tools/jol/

英文:

All instance variables are stored within the object, on the heap. There is no distinction between reference and primitive type variables in this. The value of the variable is a "reference" or "pointer" that is either the special null value, or it points to an object, through an implementation-specific mechanism (OpenJDK HotSpot JVM calls it "oop" - supposedly from "ordinary object pointer").

You can read more about the memory layout of objects in

Another matter is how instance variables are stored within the object: in what order do the go, or if they are stored packed. Instance variables are most likely not stored in source code order, but the details of this vary a lot between JVM implementations and versions.

OpenJDK now includes a tool you can use to inspect the object layout: http://openjdk.java.net/projects/code-tools/jol/

答案2

得分: 1

staticField

字符串本身存储在堆上,就像所有字符串一样。名为 `staticField` 的静态字段是一个引用,指向这个字符串。只有一个这样的引用(通常是 4 到 8 字节的内存中的一个位置指向它)。这个“内存位置”有点棘手,它通常位于堆上,与类文件存储在同一个地方。

instanceField

这个问题回答起来简单多了。实际上__根本没有这个字段__,除非有人创建一个新对象。而对象存储在堆上。想象一下完全不同的代码:

```java
public void foo() {
    Example e = new Example();
}

这会创建一个新的 Example 对象,这样一来,我们就有了一个 instanceField 的实例。Example 对象在堆上创建,它占用一些内存。其中一部分内存包括指向 "instanceField" 字符串的 4 到 8 字节长的引用(指针),该字符串也位于堆上,可能在一个完全不同的位置。然后,本地字段 e 位于堆栈上,将引用(指向)那个地址。

因此,我们有了 e(位于堆栈上),其中包含堆上 Example 对象的内存地址,并在该内存中有一个内存地址,指向堆上的不同位置,那里存储着字符串 "instanceField"

local

最后,有 local,它在堆栈上占用 4 到 8 个字节,指向位于堆上的字符串。


<details>
<summary>英文:</summary>

Given:

public class Example {
static String staticField = "staticField";
String instanceField = "instanceField";

public void foo() {
    String local = &quot;local&quot;;
}

}


## staticField

The string itself is on the heap, like all strings are. The static field named `staticField` is a reference that points at this. There&#39;s only one such reference (there is one place in memory of (usually*) 4 to 8 bytes pointing at it. This &#39;place in memory&#39; is a bit tricky as to where it lives; generally on the heap, same place class files live.

## instanceField

This is much simpler to answer. There __is no such field__, at all, until someone makes a new object. And objects are.. on the heap. Imagine some entirely different code:

public void foo() {
Example e = new Example();
}


This makes a new Example object and in so doing, we now have one instance of `instanceField`. The Example object is created on the heap, it occupies some memory. Part of that memory involves that 4 to 8 byte long reference (pointer) to the `&quot;instanceField&quot;` string, which also lives on the heap, probably in an entirely different spot. Then, the local field `e`, which lives on stack, will reference (point at) that.

So, we have `e` (living on stack), containing a memory address in the heap where an instance of `Example` lives, and within the memory used by that, there is a memory address that points at a different place on the heap where the string `&quot;instanceField&quot;` is located.


# local 
Finally, there&#39;s `local`, which is 4 to 8 bytes on the stack, pointing at a string living on the heap.

*) Any JVM is free to implement this however they want.

</details>



huangapple
  • 本文由 发表于 2020年7月26日 22:49:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/63101741.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定