Runtime vs compile time memory allocation in java

14,428

Solution 1

Compile time no memory allocation happens. Only at load and runtime.

Compile time generates .class files that's it.

Remember you need to have a main class to run the program. When you run your program using Java with classpath to .class file, there will be steps like loading & linking etc.,

Classloaders loads the files to permgen.

When main method invoked, there will be stack created and local variables will be placed there

When runtime encounters new it creates object on heap and allocates required memory there like memory required for Test.

Solution 2

Local variables and method parameters such as primitives or reference, are notionally allocated a place on the stack at compile time.

At runtime, this isn't guaranteed to to reflect how it is laid out in memory.

Allocation of objects on the heap only occurs at runtime.

how is it possible as java runs on VM which directly takes compile .class file.

Only the VM knows how the code will be compiled so it not possible to do memory allocation at compile time.

when is a assigned value 10

At the line where the assignment occurs. Given its not used, the JIT can discard it so it might no happen at all.

Also the same question stands for reference variable t.

t is assigned where the = is after the object is constructed.

Solution 3

Well, this one is a bit of a doozy and I'm not sure that you're going to get the exact answer that you want out of this entire thread, since really, what you're asking, is a major discourse in the internals of the compiler, and most people really don't care.

For the most part, the Java Compiler uses automatic memory management, so it's really up to the compiler to determine what it will or will not do, and this can change between versions.

But before I start explaining this, I want to clarity my notation:

  1. I will use [Object] when referring to a Java object that is not a primitive.
  2. I will use [object] when referring to a location in memory that has a value and an identifier.
  3. I will use [primitive] to refer to an [object] that is composed of one of the primitive types in Java (int, double, float, and so on, excluding string)
  4. String is a special case in java, and although it is an object, it may be treated differently than other objects.

    An [object] has a special property. It has a value and an identifier, and the process by which an identifier is resolved to a value and at which time it occurs depends on the type of binding.

    There is static binding, in which the binding can be resolved at compile time and the value or method of which is known at compile time. This is also known as "early" binding. For example.

    int a = 0; // AND //a direct function call, like print();

    There is also dynamic binding, in which the binding between an identifier and a value or a subprogram to a program cannot occur until runtime. This is also known as "late" binding. For example.

    public void foo(java.util.List list) { list.add("bar"); }

    There's also a hybrid kind of binding, but I'm not going to talk about that because I haven't discovered Java to have it.

    Now, binding is also very closely related to scoping, which is the idea that a variable "lives" in a certain scope. That's a topic of discourse I really don't want to go into (scoping is kind of a bear) and make this post a novel rather than a novella.

    The way memory allocation in Java works depends on a few things:

    1. If the reference to an [Object], [object], or [primitive] is known at compile time, and is it possible for static binding to occur, then the compiler is likely to allocate memory for those objects (notice how I didn't use brackets) at compile time.

    2. If the reference to an [Object], [object], or [primitive] cannot be known at compile time, and dynamic binding must be used, then the compiler is likely to allocate memory for those objects at runtime.

    The way that Java treats objects allocated at runtime differentiates depends on which binding was used for what type.

    1. Static binding
      • Objects that are a kind of [Object] will have their references placed on the stack at compile time, but their memory allocated on the heap at runtime. (Lazy).
      • Objects that are a kind of [primitive] will be bound and allocated at runtime.
      • Strings are a special case, but are generally handled like the case of an [Object]
    2. Late binding
      • Allocation on the stack and heap done at runtime.

    In summary, don't worry about it. It's a big headache for you to do so.

    If I'm wrong about any of this, someone please let me know. I'm a little bit rusty.

Solution 4

In java a class is not loaded until unless its object is created which are created at runtime so any member variables like "a" in yours will get space when class is loaded same goes for object it will be allocated space at run time.

Share:
14,428
user1649415
Author by

user1649415

Updated on June 22, 2022

Comments

  • user1649415
    user1649415 almost 2 years

    I am confused regarding whether memory allocation in java occurs at run time or compile time.

    For example:

    class Test{
      int a;
      public Test(){
        a=10;
      }
    };
    
    // somewhere else
    Test t = new Test();
    

    Is a allocated at run time or at compile time? If at compile time, how is it possible as java runs on a VM which directly takes compiled .class files?

    Also:

    • when is a assigned the value 10?

    • how does it work for reference variable t?

    Thanks.