Since JVM allocates memory to static variable type in Method Area. But when it comes to static String type does it refer to heap area from method area or it provides memory in Method Area there itself. If it refer to heap area then String will have the same behaviour(for below example)?
Example:
static String s1 = new String("Aman");
static String s2 = "Aman";
You are conflating the variables s1 and s2 with the objects they refer to.
The objects are in the heap. The literal "Aman" is in the string pool subdivision of the heap.
The variables, being static, are in the class.
Since JVM allocates memory to static variable type in Method Area.
Yes you are right, as static variables are class level variable since they are part of the reflection data (class related data, not instance related) they are stored in the PermGenSpace > Method Area section of the heap,
But when it comes to static String type does it refer to heap area
from method area or it provides memory in Method Area there itself.
See objects always get memory to heap area only no matter what, but yes static reference variables will be stored in Method Area.
Coming to your code,
static String s1 = new String("Aman");
Above line of code will create two objects 1st object through new keyword and 2nd objects through string literal "Aman" in the heap memory but remember the string literal will be stored in StringConstantPool and refer 2nd object in the heap from StringConstantPool and after that you are assigning the reference of objects which is in the heap to reference variable which is exists in MethodArea.
static String s2 = "Aman";
Now when compiler executes above line it will check "Aman" is already in the StringConstantPool it will not create another object instead it will return the same object which is already in the heap memory to static reference s2 which is in the Method Area.
I hope it will help.
Related
In Java, when we only declare a variable of a class type, only a reference is created (memory is not allocated for the object). Is to hold the reference t somewhere space will be created on heap ? or if i'm wrong then what happens exactly in memory when we just declare variable ?
Test t;
In Java, when we only declare a variable of a class type, only a reference is created (memory is not allocated for the object).
This is correct.
Is to hold the reference t somewhere space will be created on heap?
The answer depends on the context in which the declaration appears. If the said declaration is part of an object (i.e. t is a field) then the space for the reference would be allocated from the heap, along with the space for the rest of the object containing the field. Otherwise, the space for the reference would be allocated in JVM's stack frame.
When you declare a variable:
Test t;
space is made for the reference (a fixed amount, doesn't depend on the number of members in the class). When you instantiate a variable, using the new keyword:
t = new Test();
then space for the variable is made on the heap, and t references that space. This has to be large enough to hold all the members of a Test.
I know that when declaring object instances in c++ like so:
Object object
the Object constructor is called and memory is provided for that object, however i find that when you do this in java the object instance doesn't have a value until:
object = new Object()
is written. I want to know specifically when memory is provided for the object. I thought that both construction and the new keyword allocated memory so Object object = new Object() seems redundant. I read on oracle's site that declaration "reserves" memory and new "allocates" memory, I would like to know what is the difference between the two.
You need to differentiate between the space required for the variable and the space required for the object. Bear in mind that the value of the variable is just a reference - very much like a pointer in C++. So if you have:
Object x = null;
then the variable x itself takes up enough space for a reference (usually 4 or 8 bytes). Now if you have:
x = new Object();
that creates an object - the value of x is now a reference to the newly created object. x itself takes up the same amount of space as before, but there's also the space required for the object itself (basically the fields, a reference for the type of the object, and data for synchronization and house-keeping).
When you do something like
Object object = new Object()
in Java, object is a reference to the actual instance on the managed heap. Compared to C++, that's roughly doing
Object* object=new Object()
So when you do
Object object;
in Java, a place is created for the 'reference' to a instance.
Similar to
Object* object;
in C++.
Object foo=null;
in meaning of C++ creates reference foo to the object of class Object. So, it consumes memory for reference only.
Object realFoo=new Object();
creates such reference and also real object with whatever is with this object. So, it is memory for the reference and object itself.
In Java there is no memory reservation - only memory allocation.
declaration reserves memory: parameters and variables inside a method will have memory reserved for them in the stackframe.
allocates memory: at runtime, when executing "new", memory will be allocated for the new Object on the heap
It's important to understand that in Java, Object object is simply a reference to an Object called object. If you're familiar with C++, you can think of this reference as a pointer (though it's not quite the same).
On a 64-bit machine, the object reference is 8 bytes. When you actually instantiate an Object using the new keyword and assign it to the reference, this is where memory is allocated for your Object.
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?
I'm reading a book "Thinking in Java" which says
objects are stored on heap and static variable on stored on some fixed location say static storage so that they can be available for entire time program is running.
class Myclass{
static int x =0; //stored on static storage
Myclass obj = new Myclass(); //stored on heap
}
Although making a object, static will not be a good idea as far as OOPS is concerned. Putting this aside for a while. there comes my questions that
where does object which is declared static is stored.
how does JVM does instantiation in this case.
class Myclass { static Myclass obj = new Myclass(); //no man's land }
All static content will be created on class load/initiation and stored in special location (most probably part of perm gen, differs based on implementation).
For second example, When your Myclass is loaded, it's static content will be created/instantiated.
This tutorial may give you high level overview.
Static is a special memory location to the program. So the program could easily access it. Only one such location available for the program to run. And it's the place where static content is created. The JVM instantiates objects on the heap. But if you make a static reference to the object then it placed in the static memory place.
static variables are stored on method area.
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.
It depends on JVM implementation. In your example the variable is initialized to a primitive value and so it will be stored in metaspace(native memory, offheap). In case you initialized it with new ObjectClassSmthng() the object will be stored on heap and x variable (which is a reference) would be stored in metaspace.
This is true for HotSpot JDK 8.
Where does the Java JVM store primitive variables, and how is the memory used by primitives freed after use?
I guess it is on the stack?
Simplistic answer: it depends on where the variable is declared, not on its type.
Local variables are stored on the stack. Instance and static variables are stored on the heap.
Don't forget that for reference type variables, the value of a variable is a reference, not the object. (Arrays are reference types too - so if you have an int[], the values will be on the heap.)
Now, this is potentially an overly simplistic answer, because a smart VM may be able to detect if a particular reference type variable refers to an object which can never "escape" the current method. If that's the case, it could potentially inline the whole object on the stack.
But conceptually this model is accurate. So a variable of type int which is declared as an instance variable like this:
class Foo
{
private int value;
...
}
will conceptually live on the heap, as part of the data of any instance of Foo. It will be freed as part of freeing the instance - it's just 4 bytes within the block of data representing a Foo instance; it doesn't need separate deallocation.
Where a variable is stored depends on whether a variable is a local variable or an instance variable.
Local variables are stored on the stack. Instance and static variables are stored on the heap.
Let me explain this with an example. Lets say we have an instance variable animal of some custom class Animal.
Animal animal = new Dog();
Here animal is just a reference and is located on the stack. The actual object is allocated memory on the heap. This reference animal will point to this object memory allocated on the heap. So if you have 3 reference pointing to the same object.
Animal animal1 = new Dog();
Animal animal2 = new Dog();
Animal animal3 = new Dog();
All three reference will be in stack. When I say reference it is just a pointer pointing to the object on the heap. In terms of memory this reference holds the address(not actually there a bit more abstraction here) of the object on the heap. So 4 bytes on 32 bits and 8 bytes on 64 bits. Only when all the three references are dereferenced i.e they are no longer in scope(or rather no longer pointing to the original object) then only garbage collector is free to deallocate the memory allocated to the object on the heap.
There is a slight variation when we store primitive types or String literals.Unless you explicitly create their object using new() operator they are created and stored in permGen area of Heap.
So both references firstString and secondString in
String firstString = "Stack";
String secondString = "Stack";
will point to the same object in the String pool. It would point to different objects when we create them using new().
Class objects, including method code and static fields: heap.
Objects, including instance fields: heap.
Local variables and calls to methods: stack..