Where are memory address stored in Java ? What I am trying to understand is how something like the following is stored. 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 ?
What I am trying to understand is how something like the following is stored.
It depends on where that int i = 5; is:
If that's within a method and therefore i is a local variable, then 5 is stored as a local on the stack (i isn't "stored" anywhere, the bytecode generator just remembers where on the stack i is). Bytecode has specific instructions for interacting with local variables, including some quite efficient dedicated no-args versions, such as iload_0 which loads an int from "local variable 0". (Those go through iload_3, and then there's a version taking an arg, iload followed by an index.)
Consider this class:
public class Example {
public static final void main(String[] args) {
int i = 5;
System.out.println(i);
}
}
Here's the bytecode for that (you can get this by compiling it and then doing javap -c Example), with notes to the right:
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
}
Note the two different uses of the stack there: The "locals" are on the part of the stack that the method allocated itself for locals (since it knows in advance how many there are), and then there's the dynamic part following that that it uses for passing information into methods and such.
If that's within a class definition and therefore i is an instance field of the class, i is part of the structure that Java reserves (either on the stack or heap, sometimes moving between them) for the instance.
Bytecode doesn't really shed a lot of light on this, but consider this class:
public class Example {
int i = 5;
public static final void main(String[] args) {
Example ex = new Example();
System.out.println(ex.i);
}
}
Here's the bytecode for that:
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
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With