英文:
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”)。
关于对象的内存布局,您可以阅读更多信息:
- https://www.baeldung.com/java-memory-layout
- http://psy-lob-saw.blogspot.com/2013/05/know-thy-java-object-memory-layout.html
另一个问题是实例变量在对象内部的存储方式:它们的排列顺序是怎样的,或者它们是否被紧密地存储。实例变量很可能不是按照源代码顺序存储的,但这方面的细节在不同的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
- https://www.baeldung.com/java-memory-layout
- http://psy-lob-saw.blogspot.com/2013/05/know-thy-java-object-memory-layout.html
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 = "local";
}
}
## 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's only one such reference (there is one place in memory of (usually*) 4 to 8 bytes pointing at it. This 'place in memory' 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 `"instanceField"` 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 `"instanceField"` is located.
# local
Finally, there'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>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论