Java中的内存地址存储在哪里?我想要理解的是以下内容的存储方式。我已经知道堆栈和堆之间的区别,但想更深入地挖掘一层。
int i = 5;
i
和5
是分别存储的,然后建立映射关系吗?
同样地,我们说对于32位版本最多可以有4GB RAM(实际上要少得多),那么这些内存块的内存地址存储在哪里呢?
Java中的内存地址存储在哪里?我想要理解的是以下内容的存储方式。我已经知道堆栈和堆之间的区别,但想更深入地挖掘一层。
int i = 5;
i
和5
是分别存储的,然后建立映射关系吗?
同样地,我们说对于32位版本最多可以有4GB RAM(实际上要少得多),那么这些内存块的内存地址存储在哪里呢?
int i = 5;
的位置:i
是一个局部变量,那么 5
作为栈上的局部变量存储(i
不会“存储”在任何地方,字节码生成器只是记住了 i
在栈上的位置)。字节码具有用于与局部变量交互的特定指令,包括一些非常高效的专用无参版本,例如从“局部变量0”加载 int
的 iload_0
。(这些通过 iload_3
进行,然后有一个带参数的版本,iload
后跟索引。)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
}
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
}
int i = 5;
是i和5分别存储,然后建立映射吗?
在运行时,这个值很可能已经被内联优化掉了。但是,它可能存在于堆栈、堆或两者中,具体取决于上下文。
同样的,我们说对于32位版本,最多只能有4GB的RAM(实际上要少得多),所有这些内存块的内存地址都存储在哪里?
在32位版本中,您只能使用可用的最大连续区域作为堆。这在Windows上限制为约1.4GB,在Unix上限制为约3GB。
在64位版本中,通常使用32位引用,通过翻译允许您寻址多达32GB(Java 7)和64GB(Java 8)。没有压缩指针(Compressed Oops),您可以在大多数操作系统上寻址48位地址空间(受硬件和操作系统的限制)。
i
并没有被“存储”。它只是内存中某个位置的别名。而数字5
则被存储在该位置上。 - NPE