1

I've been learning Java for almost a year, but still feel confused when it comes to dynamic memory allocation.

Question 1: Can anyone elaborate what happens in memory when below code get executed based on the steps I wrote (Please correct me if I was wrong)? The more detailed the better.

Question 2: What kind of book/website should I read/visit if I want to dig deeper into JVM or Java memory?

class Student {
  private static int counter;
  private String name;
  private int age;
  private String grade = "grade 1";

  Student(String _name, int _age) {
     this.name = _name;
     this.age = _age;
  }

  public static void main(String[] args){
     Student s = new Student("Emma", 6);
  }
}
  1. Student.classfile get loaded, static variablecounterare initialized on data area.
  2. main()get called, JVM allocates memory on stack for local variables.
  3. JVM allocates storage for member variablesname,ageandgradeon heap, and zeros the storage.
  4. gradeget initialized as"grade 1".
  5. constructorStudent()get called to initialize the new instance: JVM allocates memory for_nameand_ageon stack, initialize them to"Emma"and6, then copy their values to member variablesnameandage.
  6. JVM assign this new instance tos.
6
  • 1
    That seems like a pretty accurate description to me. Was there something there you're unsure about? And your second question is probably off-topic for Stack Overflow. There's a bit of a mandate for us to avoid recommending resources here. Commented Nov 14, 2016 at 9:36
  • Fore sure you have to swap the points (1) are (2). The static members of a class are initialized after that the class-loader has finished the loading of the class Student. Commented Nov 14, 2016 at 9:37
  • 1
    @Sandro The class has to get loaded before any of its methods can be run. Swapping points (1) and (2) would be impossible. Commented Nov 14, 2016 at 9:39
  • Have a look at this visualization of your code. It will show you what is placed on the stack and what is placed on the heap. cscircles.cemc.uwaterloo.ca/java_visualize/… Commented Nov 14, 2016 at 9:40
  • @DavidWallace Sorry! You are right! I did not see that the main function is inside the Student class. Commented Nov 14, 2016 at 9:41

2 Answers 2

2

You have 4 and 5 out of order. Constructors first call super() in one form or another, then all initializers and anonymous init blocks, in textual order, then their own body after thesuper() call if any. You also have the allocation and initialization of _name and _age in the wrong place: it happens before the constructor is called. See the JLS and JVM Specification for details.

Sign up to request clarification or add additional context in comments.

3 Comments

The other important thing is that some (or maybe even all) of these steps might not happen at all. The only guarantee you get is that the program will be indistinguishable from a program where all these steps happened.
@biziclop super() is called unless the current class is java.lang.Object, which it isn't. Calling all initializers and anonymous init blocks already includes the case where there aren't any. The OP's constructor isn't empty, so its body gets executed as well. The part about allocating and assigning the constructor parameters isn't optional in the OP's code either. There is nothing in the JLS or JVM Spec about an 'as-if' rule. Are you thinking of C?
A lot of JLS rules are formulated in an as-if mode. That's what makes Hotspot optimisations possible. So for starters the whole main() method may be detected as having no observable side-effects and thus eliminated completely. Even if it isn't, escape analysis might prompt the VM to decide to create the object on the stack. And so on.
0

Some notes;

On newer versions of Java, there is no guarantee that a static field will be initialised if it is never used.

Space for an object is initialised all at once, not on a per field basis. The whole object is zero-ed out (except for the header) not just where the fields are held. i.e. the object has padding it is zeroed out, and it is no slower to zero out eight byte fields than a single long field.

The constructor is called before any field in an object is assigned a value no matter how the code is written.

The first time a String literal is used the String and the underlying char[] or byte[] is also created. grade is initialised to a reference to that object.

As @biziclop points out it is possible (not just in theory) that none of these things will happen as the whole code can be optimised to nothing (and the JIT can do this today) The only thing which it doesn't do is prevent the String literal from being created as it this happens long before the code has warmed up enough to determine the code doesn't do anything.

Note: with an AOT coming to Java 9, it is possible the code will be reduced to a NO-OP.

1 Comment

String literal objects are created on class loading, not on first use.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.