Java Class instantiating - What goes inside memory? - java

I have a basic question. Consider this simple code:
class A{
void someMethod(){
B b = new B(); // Line 3
B c = new B(); // Line 4
}
}
When Line 3 is executed, class B is loaded into memory (i.e.: we have physical space allocated for a object of type 'Class' ( Let's say with an id - classLaoder1.B) of type class containing code for class B).
Question 1# What happens next? - Instance of class B(representing state of b) is created(allocated physical memory) based on the fact that classLoader.B actually contains B's information?
Question 2# Also, at Line -4, the since classLoader.B is present in memory, an object containing state of c is created in memory?

Well, your example and the description are a bit to vague to answer your question in a short manner.
You are referring to different classloaders but you didn't include any exemplary code when which class is loaded. In its current form the code won't even compile as the return value is missing - but let's continue with your question.
The heap is a memory area created by the JVM at startup and may increase and decrease at runtime dynamically. It is divided into different sections. YoungGen will hold short lived objects, OldGen will hold object states of objects that survived the YoungGen space and finally the PermGen space which as it names suggest should contain permanent class metadata and descriptors. Therefore, the PermGen space is reserved for classes and stuff that is tied to classes (like static members) and you will have to deal with it if you handle application servers or plugin-mechanisms that provide some kind of hot-deployment features. (To be a bit more precise, in Sun's JVM the PermGen space is actually a separate part of memory and does not really belong to the heap, but different JVM vendors may have different definitions therefore)
Reference: Configuration and Setup of SAP JVM
Two cases may occur upon invoking someMethod():
B was already loaded by the application classloader on startup of your application
B is included within a class that got loaded by a child classloader
In the first case the memory for the class definition is allocated at startup within the PermGen space of the heap and is only freed when the application shuts down. In the latter case, there is also memory for that class stored in the PermGen space of the heap, but on invoking loadClass(...) of the class-loader which should load the class. Here, memory can be freed if no strong reference is pointing to any class loaded by that class-loader. Often, enums or singleton classes, which hold a strong reference to themselves, will prevent however a correct unloading of those loaded bytes and create a memory leak therefore.
If you ever implement one of those application-frameworks and debug it, you will see what exactly happens when. To load a class via a class-loader the loadClass(...) method is called which first checks if it already has loaded that class before then asks his parent if she knows this class (which also checks if she has loaded that class or her parent, ...). Only if the class was not loaded before (by either this class-loader or any parent) the current (child) class-loader is going to execute findClass(...) which further should call defineClass() which actually turns the bytes from some input-file or stream to a Class representation. That Class object contains the blueprint (signature of the method including number and type of parameters, return value and thrown exceptions). On trying to load a class, usually the extension class as well as the defined interfaces get loaded too (if not already known in the class-loader tree) - but the types of including members are not yet loaded! They will get loaded when the class is going to be instantiated.
Reference: How ClassLoader Works in Java
On creating a new instance, the new operator invokes the newInstance(...) method internally and reserves memory for all members of that instance. So, if the type of the member is yet unknown by the current class-loader or its parents, it will be loaded before assigning any values. Then, the constructor of the class is executed (according to the constructor called with the new operation) and values get assigned to the memory occupied by the variables on the heap (often in Eden space). After the object is constructed in memory, a reference to the object is returned by the new operator and the object is ready to be used within your code.
c in your example is instantiated the same way as b - first the classloader has to check if class B was already loaded. As it has loaded B before, it just grabs B from its local cache and returns the class therefore. Next, the newInstance(...) method is executed on the class to instantiate a new object. Therefore, again memory for the member variables is allocated on the heap - after the initial check if the required classes have already been loaded - the constructor is executed and the reference to the newly created and initialized object is returned.
If your class has static methods or static members they will get allocated onto the PermGen space, as they belong to the class and are shared across all instances.
One thing to note: If c should be loaded by a peer or peer's child class-loader (CL2) and b was defined by a sister class-loader (CL1) (so no parent has actually defined the class), the peer class-loader CL2 will load (and define) its own version of B which seems to be the same as the version of the sister's loader CL1, but they actually are different classes for Java as the class-loader which loaded that class is actually part of the class. This means CL1-B != CL2-B although both versions share the same methods and fields. Casting c to b's B will result in a ClassCastException therefore.
Just for completeness, although you didn't ask for this, on calling methods a different kind of memory allocation occurs. The passed variables are pushed onto the stack, which every thread has its own instance of, and popped from the stack (including return value) if the method returns. Furthermore, each block (The part between { and }) creates a new stack-frame (that's why variables declared inside a block are not visible to a region outside of the block) where the local variables of that block are stored into. More information available here
Reference: Understanding Stack and Heap-Tutorial

b and c are instances of the Class B, consider them variables, so they will be stored in memory separately. b contains information of the class B (the class is equivalent to a structure) so you may have a class Person that has the variable name, and you have 2 instances: p1 and p2. Each one will have a different name and a different place in memory

Related

Instance variable of a static nested class vs static variable of an outer class

I was using a static nested class in java for a particular use-case. A minimal example of the same is shown below:
public class Foo {
static int fooInner = getInner(); // CASE 1
private static class StaticFoo {
int fooInner = getInner(); // CASE 2
public int useFooInner(){
System.out.println(fooInner);
//do something
}
}
}
The question is how is the memory allocation in Case 1 different from that in case 2? Or is it the same?
What if I make the case 2 variable static too. Will the memory usage differ?
NOTE: Please do not mention that shadowing will take place. Although I have put both the variables there, but it's an "OR" case and that's why the "CASE"s.
PS: I feel that the memory usage should be the same. Since the nested class is static, it won't be created for every object and thus the instance variable fooInner (Case 2) will also be created just once. Thus, the getInner() function would run just once. But it is just at an abstract level + gut feeling. A more descriptive answer would be appreciated!
They are different.
From a memory allocation point of view, a static inner class is no different from a top level class. Your StaticFoo will be compiled to a class (Foo$StaticFoo.class) that is essentially independent from its parent class at runtime. At compile time, there are access checks for private members.
So, in case 1, you have a static field in a class. It will be allocated as a field on a Foo.class object on the heap. There will only be one instance per ClassLoader that loads the Foo class, which generally means just one shared instance for the whole JVM.
In case 2, you have an instance field in the Foo$StaticFoo class. On the heap, there will be space allocated (and a value assigned) for (and in) each instance of StaticFoo created. Each StaticFoo that gets created will access its own instance of that field, and since it's not final, the value of each instance can be independently changed.
If you changed StaticFoo.fooInner to be static, then it would be exactly the same as case 1.
Note: The above is true only for Java 8 and later. For earlier JVMs, that amount of memory allocated in each case still matches the description above, but static variables, as well as being singletons per ClassLoader, are also stored in a different memory pool: PermGen Space rather than the main heap. See this answer for more details.

In Java, when we instantiate some class, does the JVM actually create a separate "object" for each supertype? [duplicate]

Lets say I have a class A.java,
When I will execute a constructor method of A, it will create a memory space for xyz Object.
A xyz = new A();
The reference to memory may be something like,
[xyz] ---> '0x34524'
Thats basics of OOP. Simple enough!
Now,
What happens if a class is inheriting from different parent classes? How many object space will be created in memory?
Lets say we have,
and then we create an object of class D.java,
D omg = new D();
Here as we know that D's object will call construct of C.java and so on until A.java. Does this mean that in memory we are having 4 different memory reference, because we are instantiating all of the four objects (one directly and another 3 indirectly)?
[omg] ---> '0x34525'
[C] ---> '0x34526'
[B] ---> '0x34527'
[A] ---> '0x34528'
Note :
This isn't homework question, this is just a curiosity question.
I am aware of the fact that if we have a instance variable inside an A.java then we will not create only object A but we will be creating other internal object whenever we hit new keyword.
First, a tid bit... calling the constructor of an object does not allocate it. In bytecode, the initialization new Object() is expressed as something to the effect of...
new java/lang/Object
invokespecial java/lang/Object <init>()V
The new instruction takes care of allocating the space and acquiring a reference to the yet uninitialized object, while the invokespecial handles calling the constructor itself (which is internally compiled to a void method named <init>, hence the descriptor <init>()V).
Moving on, internals of object allocation and representation on the heap are entirely JVM specific. However, as far as I know, there is only one allocated object per allocated object, no matter its number of super classes. The object itself in memory has space for the instance fields of both its own class and its super classes. It must also have space for a virtual method table, in order to do virtual dispatch when performing virtual method calls (e.g. via invokevirtual) for the object.
Internally, the Oracle HotSpot JVM manages things called oops, or ordinary object pointers. You can read more about the HotSpot memory layout here. Feel free to browse the HotSpot source repository.
JVM allocates memory for only one object (here D)
memory allocation and initialization happens bottom(here D) to top(Object)
initialization/calling constructors happens Top(Object) to Bottom(here D)
reference :
http://www.artima.com/designtechniques/initialization.html
I have not read this anywhere but its my experience.
When you call new D(), the constructor chain begins, it first creates an java.lang.Object and then extends it to an A, I mean after creating the Object (which is root of all objects), A is initialized on it, by adding memory for A's members, including fields and methods (which are a pointer to some code!). And then it extends to B and so on.
In the process of extension if a method is overriden, the method pointer in the object will point to new code.
It will be only one reference to D.

objects lives on heap .it consist of instance variable .does it contains method also and when we call a method from object how it goes to stack?

An object lives on the heap. It consists of instance variables. Does it contain methods too, and when we call a method from the object how does it go to the stack?
if I create an object
Test obj=new Test();
obj.start();
Where is the method code ? Is it in object in heap memory or somewhere else?
The method code is not in the heap - it is in a static area of memory that is populated when the class data is loaded. An object instance contains a reference to this static memory area that allows the runtime system to look up the appropriate method when it is called - this is how method overriding works. Let's say you're calling an instance's equals method - at runtime the JVM looks into the class's static memory area, and either finds the address of an overridden equals method or else it follows a link to the superclass's static memory area in order to find its equals method, stopping when the JVM finds an overridden equals method or else when the JVM finds the Object memory area with its default equals method.
The method code is not duplicated for every instance. Each method is stored only once.
As seen in http://javapapers.com/core-java/java-jvm-memory-types/:
(...) method area is part of non-heap memory. It stores per-class structures, code for methods and constructors. Per-class structure means runtime constants and static fields.
See also: Where methods live? Stack or in Heap?

Inheritance and Object creation, Theoretically and in Real

Lets say I have a class A.java,
When I will execute a constructor method of A, it will create a memory space for xyz Object.
A xyz = new A();
The reference to memory may be something like,
[xyz] ---> '0x34524'
Thats basics of OOP. Simple enough!
Now,
What happens if a class is inheriting from different parent classes? How many object space will be created in memory?
Lets say we have,
and then we create an object of class D.java,
D omg = new D();
Here as we know that D's object will call construct of C.java and so on until A.java. Does this mean that in memory we are having 4 different memory reference, because we are instantiating all of the four objects (one directly and another 3 indirectly)?
[omg] ---> '0x34525'
[C] ---> '0x34526'
[B] ---> '0x34527'
[A] ---> '0x34528'
Note :
This isn't homework question, this is just a curiosity question.
I am aware of the fact that if we have a instance variable inside an A.java then we will not create only object A but we will be creating other internal object whenever we hit new keyword.
First, a tid bit... calling the constructor of an object does not allocate it. In bytecode, the initialization new Object() is expressed as something to the effect of...
new java/lang/Object
invokespecial java/lang/Object <init>()V
The new instruction takes care of allocating the space and acquiring a reference to the yet uninitialized object, while the invokespecial handles calling the constructor itself (which is internally compiled to a void method named <init>, hence the descriptor <init>()V).
Moving on, internals of object allocation and representation on the heap are entirely JVM specific. However, as far as I know, there is only one allocated object per allocated object, no matter its number of super classes. The object itself in memory has space for the instance fields of both its own class and its super classes. It must also have space for a virtual method table, in order to do virtual dispatch when performing virtual method calls (e.g. via invokevirtual) for the object.
Internally, the Oracle HotSpot JVM manages things called oops, or ordinary object pointers. You can read more about the HotSpot memory layout here. Feel free to browse the HotSpot source repository.
JVM allocates memory for only one object (here D)
memory allocation and initialization happens bottom(here D) to top(Object)
initialization/calling constructors happens Top(Object) to Bottom(here D)
reference :
http://www.artima.com/designtechniques/initialization.html
I have not read this anywhere but its my experience.
When you call new D(), the constructor chain begins, it first creates an java.lang.Object and then extends it to an A, I mean after creating the Object (which is root of all objects), A is initialized on it, by adding memory for A's members, including fields and methods (which are a pointer to some code!). And then it extends to B and so on.
In the process of extension if a method is overriden, the method pointer in the object will point to new code.
It will be only one reference to D.

Where instance variables(primitives) are stored in java? Is anyhow stack related to instance variables storage?

Where instance variables(primitives) are stored in java?
Primitive variables are stored in the same places all variables are stored (including references):
Within objects created (allocated) on the heap, or
Within method stack frames as local variables, or
Within static areas of their containing class (which are on the heap).
If you mean instance fields declared on a class, they are allocated on the heap as part of the object's own allocation.
Primitive (value type) variables declared as method locals are stored in the method's stack frame.
After class loader loads classes with qualified name into the jvm . JVM parse the binary data from the class and place that info into the Method area. When JVM executes the class it first place the Objects (including instance fields primitive/non primitive) into the heap.

Categories