Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where are memory addresses stored in Java

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 ?

like image 533
Andy897 Avatar asked Nov 15 '25 18:11

Andy897


1 Answers

What I am trying to understand is how something like the following is stored.

It depends on where that int i = 5; is:

Local Variable

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.

Instance field

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
}
like image 77
T.J. Crowder Avatar answered Nov 18 '25 08:11

T.J. Crowder