Java 中存储的内存地址在哪里
Where are memory addresses stored in Java
Java 中存储的内存地址在哪里?我想了解的是如何存储以下内容。我已经知道堆栈和堆之间的区别,但试图更深入地挖掘一层。
int i = 5;
是i
和5
分开存放,然后建立映射?
同理,我们说32位的版本最多可以有4GB RAM(现实中少得多),所有这些内存块的内存地址都存储在哪里?
What I am trying to understand is how something like the following is stored.
这取决于 int i = 5;
所在的位置:
局部变量
如果它在一个方法中,因此 i
是一个局部变量,那么 5
将作为局部变量存储在堆栈中(i
不是 "stored"在任何地方,字节码生成器只记得堆栈上的位置 i
)。字节码有与局部变量交互的特定指令,包括一些非常有效的专用无参数版本,例如 iload_0
从 "local variable 0" 加载 int
。 (那些通过 iload_3
,然后有一个版本采用 arg,iload
后跟一个索引。)
考虑这个 class:
public class Example {
public static final void main(String[] args) {
int i = 5;
System.out.println(i);
}
}
这是它的字节码(你可以通过编译它然后执行 javap -c Example
来获得它),右边有注释:
public class Example {
// ...omitted constructor stuff...
public static final void main(java.lang.String[]);
Code:
// The `int i = 5;` line:
0: iconst_5 // Load the constant 5 onto the stack
1: istore_1 // Store it in local variable 1
// The `System.out.println(i);` line:
2: getstatic #2 // Get the static field java/lang/System.out:Ljava/io/PrintStream onto the stack
5: iload_1 // Load int variable 1 on the stack
6: invokevirtual #3 // Call java/io/PrintStream.println, which gets
// the stream and what to write from the stack
9: return
}
请注意堆栈的两种不同用途:"locals" 位于方法为局部变量分配自身的堆栈部分(因为它事先知道有多少),然后是接下来的动态部分用于将信息传递给方法等。
实例字段
如果它在 class 定义中,因此 i
是 class 的实例字段,i
是 Java 结构的一部分为实例保留(在堆栈或堆上,有时在它们之间移动)。
字节码并没有真正阐明 很多,但请考虑一下 class:
public class Example {
int i = 5;
public static final void main(String[] args) {
Example ex = new Example();
System.out.println(ex.i);
}
}
这是字节码:
public class Example {
// Here's the instance field
int i;
// ...omitted the constructor stuff...
public static final void main(java.lang.String[]);
Code:
// Create our Example instance and save it in a local variable
0: new #3
3: dup
4: invokespecial #4
7: astore_1
// The `System.out.println(ex.i)` line:
8: getstatic #5 // Get the java/lang/System.out:Ljava/io/PrintStream field
11: aload_1 // Get `ex` onto the stack
12: getfield #2 // Get the value of field `i` onto the stack from the instance we just put on the stack (pops the instance off)
15: invokevirtual #6 // Call java/io/PrintStream.println, which
// again gets the stream to write to and
// what to write from the stack
18: return
}
Where are memory address stored in Java ?
在 Java 中,引用不仅仅是内存地址,而且由于压缩的 oops,它们很少用于 Java 相关数据。
What I am trying to understand is how something like the following is stored.
值得记住的是,JVM 是一个虚拟机,您可以说它在理论上是如何存储在字节代码中的,但代码本身会经历多个优化阶段,并且每次都可能发生变化。
此外,JVM 非常擅长优化不执行任何操作的代码,因此在许多微不足道的情况下,答案是;无处可去,代码已被内联化为空。
I already know the difference between stack and heap but trying to dig a layer deeper than that.
int i = 5;
Is i stored separately and 5 stored separately, and then a mapping is established?
在运行时,很可能该值已被内联而不存在。但是,它可能在堆栈、堆或两者上,具体取决于上下文。
Similarly, we say that for a 32 bit version one can have at most 4 GB RAM (much less in reality), where are the memory addresses of all these memory blocks are stored ?
在 32 位版本中,您只能使用可用的最大连续区域作为堆。在 windows 上限制为大约 1.4 GB,在 Unix 上限制为大约 3 GB。
在 64-it 版本中,它通常使用经过转换的 32 位引用,最多允许您寻址 32 GB (Java 7) 和 64 GB (Java 8) 如果没有 Compressed Oops
,你可以在大多数 OSes 上寻址 48 位地址 space(受限于硬件和 OS)
Java 中存储的内存地址在哪里?我想了解的是如何存储以下内容。我已经知道堆栈和堆之间的区别,但试图更深入地挖掘一层。
int i = 5;
是i
和5
分开存放,然后建立映射?
同理,我们说32位的版本最多可以有4GB RAM(现实中少得多),所有这些内存块的内存地址都存储在哪里?
What I am trying to understand is how something like the following is stored.
这取决于 int i = 5;
所在的位置:
局部变量
如果它在一个方法中,因此 i
是一个局部变量,那么 5
将作为局部变量存储在堆栈中(i
不是 "stored"在任何地方,字节码生成器只记得堆栈上的位置 i
)。字节码有与局部变量交互的特定指令,包括一些非常有效的专用无参数版本,例如 iload_0
从 "local variable 0" 加载 int
。 (那些通过 iload_3
,然后有一个版本采用 arg,iload
后跟一个索引。)
考虑这个 class:
public class Example {
public static final void main(String[] args) {
int i = 5;
System.out.println(i);
}
}
这是它的字节码(你可以通过编译它然后执行 javap -c Example
来获得它),右边有注释:
public class Example {
// ...omitted constructor stuff...
public static final void main(java.lang.String[]);
Code:
// The `int i = 5;` line:
0: iconst_5 // Load the constant 5 onto the stack
1: istore_1 // Store it in local variable 1
// The `System.out.println(i);` line:
2: getstatic #2 // Get the static field java/lang/System.out:Ljava/io/PrintStream onto the stack
5: iload_1 // Load int variable 1 on the stack
6: invokevirtual #3 // Call java/io/PrintStream.println, which gets
// the stream and what to write from the stack
9: return
}
请注意堆栈的两种不同用途:"locals" 位于方法为局部变量分配自身的堆栈部分(因为它事先知道有多少),然后是接下来的动态部分用于将信息传递给方法等。
实例字段
如果它在 class 定义中,因此 i
是 class 的实例字段,i
是 Java 结构的一部分为实例保留(在堆栈或堆上,有时在它们之间移动)。
字节码并没有真正阐明 很多,但请考虑一下 class:
public class Example {
int i = 5;
public static final void main(String[] args) {
Example ex = new Example();
System.out.println(ex.i);
}
}
这是字节码:
public class Example {
// Here's the instance field
int i;
// ...omitted the constructor stuff...
public static final void main(java.lang.String[]);
Code:
// Create our Example instance and save it in a local variable
0: new #3
3: dup
4: invokespecial #4
7: astore_1
// The `System.out.println(ex.i)` line:
8: getstatic #5 // Get the java/lang/System.out:Ljava/io/PrintStream field
11: aload_1 // Get `ex` onto the stack
12: getfield #2 // Get the value of field `i` onto the stack from the instance we just put on the stack (pops the instance off)
15: invokevirtual #6 // Call java/io/PrintStream.println, which
// again gets the stream to write to and
// what to write from the stack
18: return
}
Where are memory address stored in Java ?
在 Java 中,引用不仅仅是内存地址,而且由于压缩的 oops,它们很少用于 Java 相关数据。
What I am trying to understand is how something like the following is stored.
值得记住的是,JVM 是一个虚拟机,您可以说它在理论上是如何存储在字节代码中的,但代码本身会经历多个优化阶段,并且每次都可能发生变化。
此外,JVM 非常擅长优化不执行任何操作的代码,因此在许多微不足道的情况下,答案是;无处可去,代码已被内联化为空。
I already know the difference between stack and heap but trying to dig a layer deeper than that.
int i = 5;
Is i stored separately and 5 stored separately, and then a mapping is established?
在运行时,很可能该值已被内联而不存在。但是,它可能在堆栈、堆或两者上,具体取决于上下文。
Similarly, we say that for a 32 bit version one can have at most 4 GB RAM (much less in reality), where are the memory addresses of all these memory blocks are stored ?
在 32 位版本中,您只能使用可用的最大连续区域作为堆。在 windows 上限制为大约 1.4 GB,在 Unix 上限制为大约 3 GB。
在 64-it 版本中,它通常使用经过转换的 32 位引用,最多允许您寻址 32 GB (Java 7) 和 64 GB (Java 8) 如果没有 Compressed Oops
,你可以在大多数 OSes 上寻址 48 位地址 space(受限于硬件和 OS)