I am currently learning the memory concepts of java, the stack and the heap, I know that local variables and method calls lived in a place called stack. and objects lived inside a heap. but what if that local variable holds an object? or has an object reference?
public void Something(){
Duck d = new Duck(24);
}
Does it still live inside a stack? and where do instance variables live? please keep it simple as possible. thank you.
Local variable d (allocated on stack) contains a reference to an object of class Duck. In general objects are allocated on the heap.
Java 6e14 added support for something called 'escape analysis'. When you enable it with -XX:+DoEscapeAnalysis switch, then if JVM determines that an object is created in a method, used only in that method and there is no way for reference to the object to 'escape' that method - that is, we can be sure that the object is not referenced after method completes - JVM can allocate it on stack (treating all its fields as if they were local variables). This would probably happen in your example.
Fields are allocated with the rest of the object, so on the heap or on the stack, depending of escape analysis results.
Object reference variables work. just like primitive variables-if the reference is declared as a local variable, it goes on the stack.else if refrence is instance variable it will go into the heap within an object.
Related
suppose i have a code snippet like this:-
class A {
void help() {
Help helper = new Help();
}
}
in the above case, the object reference helper will be allocated memory in the stack.
now if i have a case like this
class A {
Help helper = new Help();
}
in this case, helper will not be allocated memory inside of a stack frame(I am sure of that).
will it behave like an instance variable and will be allocated space inside of an object on heap.
This type of declaration is only located to your instance. the helper attribute will be assigned each time you instanciate you Class A.
It is definitely an instance variable. it goes in the heap
In order to separate the instance and the variable you can use static attribute. Then it is linked to the class so it goes in the code segment.
Yes, You are correct. In the second case, the Help object will behave as an instance variable of the class.
When you declare the object inside the function, stack memory is used up (local variables). Whereas for instance variables ,heap memory is used.
Yes, in the second case the memory will be allocated to object helper as soon as the object of class A will be initialized but in the first case the memory will be allocated on the stack to the function named void help() and will be destroyed as soon as the function ends because helper object is a local variable to this function.
There is a difference between object and reference variable. For example:
//Here 'helper' is the reference variable
Helper helper = new Helper ();
Whenever we create any object (new Helper()), it’s always created in the Heap space and it's reference (helper) in the Stack space.
Java Stack memory is used for execution of a thread. They contain
method specific values that are short-lived and references to other
objects in the heap that are getting referred from the method.
(Source: https://www.journaldev.com/4098/java-heap-space-vs-stack-memory#java-stack-memory)
So the two objects are stored in the heap but their two reference variables are stored in different stacks.
I don't have much idea on Java.
I was going through few links and found blog says "Java Primitives stored on stack", which I feel it depends on instance variable or local variable.
After going through several links my conclusion is,
Class variables – primitives – are stored on heap as a part of Object which it contains.
Class variables – object(User Defined) – are stored on heap as a part of Object which it contains. This is true for both reference and actual object.
Method Variables – Primitives – are stored on stack as a part of that stack frame.
Method Variables – object(User Defined) – are stored on heap but a reference to that area on heap is stored on stack as a part of that stack frame.
References can also be get stored on heap if Object contains another object in it.
Static methods (in fact all methods) as well as static variables are stored in heap.
Please correct me if my understanding is wrong. Thanks.
There are some optimizations in the JVM that may even use the Stack for Objects, this reduces the garbage collection effort.
Classes are stored on a special part of the heap, but that depends on the JVM you use. (Permgen f.e. in Hotspot <= 24).
In general you should not have to think about where the data is stored, but more about the semantics like visibility and how long something lives. Your explanation in the questions looks good so far.
"Method Variables – object(User Defined) – are stored on heap but ..."
Wrong.
First, method variables are called local variables.
Let's consider
public static void main(String[] args) {
List<Integer> model = new ArrayList<Integer>();
Variable model is placed in the stack frame, not on heap. The referenced object generated with new ArrayList<Integer>() is placed in the heap but it is not a local variable.
The 3 things:
variable model
generated object
reference to that object, stored in a variable
are quite different, do not mess them up.
Object are stored in the Heap.
The object reference stored in the stack.
Static variable stored in the method area.
Example
abc obj=new abc();
abc object save in the heap and the object reference is stored in the stack.
static int i=10;
i variable stored in the method area.
I have a doubt with the management of the objects using java or c++.
The case is, in c++, when you want to create a dynamic object, one that survive more than the block scope on where it is created, you have to do a new and you will receive a pointer. Otherwise, if you just want to use this object in the block scope, you don't need to create it using new...
But in Java, you always have to create them using new, because if not, the object is null and you can use it.
Why is that? Is it just how it works?
Thanks
The best analogy I can think of, is that all types in C++ behave somewhat like primitives in Java. If you declare a primitive in Java, you don't have to use new, you can just use the variable right away. But such a primitive, much like most objects in C++, will only survive the current scope. In C++, if you want an object to exist outside of the current scope, you need to tell this to your compiler, because it will have to allocate memory on the heap instead of the stack. You can do this by using new. In Java, all objects (save primitives) are allocated on the heap, the only data on the stack are references to heap memory, and primitives. Therefor, in Java, all memory allocations are done using new.
The above is a simplification of the actual memory management in Java. For a more thorough discussion on stack/heap memory regarding primitives, take a look here.
This difference is becaase Java is using a garbage collector for memory management. Since the garbage collector automatically deallocates objects when their scope ends (and it has no reachable reference), there is no need to have two different methods for creating objects.
You can say that objects in Java automatically behaves like objects in C++ which are initialized without new, in that you don't have to think about deleting them.
Basically, that's just how it works. Once the new keyword is used then the Object is created and popped onto the heap. If you do not reference the object outside of a method then it will be automatically reclaimed by the garbage collector.
I suggest that you do some reading around the basics of the Java heap and garbage collection to get a better understanding. There are plenty of resources out there. I always recommend the head first books for new comers.
In C++, anything can be allocated on a stack (which is what happens when you say
ObjectType o;
in C++.
In Java, only primitives are really allocated on the stack. Objects are never on the stack (It's just how it is). When you say
ObjectType o;
in Java, no object is allocated, only a "variable". A variable can have a reference to an object, but at the moment it has none. In essence, it's the same thing as saying
ObjectType *o = NULL
in C++.
In order to actually allocate an object for this reference to refer to, you have to use new in Java.
The case is, in c++, when you want to create a dynamic object, one that survive more than the block scope on where it is created, you have to do a new and you will receive a pointer.
The new operator in C++ allocates space on the heap. The heap is where the larger part of the main memory is. If you do this, you are responsible for freeing that space when you're done with it using the free operator.
Otherwise, if you just want to use this object in the block scope, you don't need to create it using new...
When you declare variables in C++, memory is allocated on the stack. The stack is where local data is stored and everything you push(add) on it while executing a function will be automatically popped (removed) when the function returns. The stack is usually a lot smaller than the heap, but there are advantages to using it: you don't need to worry about memory management, it is faster, etc.
But in Java, you always have to create them using new, because if not, the object is null and you can use it.
When you declare variables in Java, they are again stored on the stack
As you know, you don't call new on primitive data types (e.g. int i = new int(3);). When you do something like Object x; you declare that x would be a reference to an object of type Object. However, you do not assign a value to it, so the reference is null (not the object, because there isn't one).
The new operator in Java, roughly speaking, allocates space on the heap, calls the constructor of the object that it is invoked on, and returns a reference to the constructed object. The difference with C++ is that you don't need to free the object yourself - there is a garbage collector. In essence, what it does is that it monitors how many references point to an object, and if they go down to zero it deletes the object automatically.
So when you do Object y = new Object();
x = y; you will get two references (x and y) pointing to the same object. When you have a function call like thisObject foo() {
Object y = new Object();
return y;
}
void bar() {
Object x = foo();
...
} in the ... part of bar() you would have the reference x, pointing to the object created in foo(). Since foo has returned, the y reference has been freed, thus there would be only one reference to this object in the ... part of the program. If you don't copy the x reference anywhere in bar and bar returns, then there would be 0 references to the object, and the garbage collector would collect it (although not immediately).
-Stan
I do know that in Java, (perhaps in .net too) , primitives are stored on stacks , where as reference types are stored on heaps.
My question was that I do not understand the proc/cons for this behavior. Why can't we reference a memory location inside our stacks instead? . I couldn't find a proper explanation as I googled ( maybe I suck at it) , but if you people can provide some insights I would be grateful
Thanks.
I do know that in Java, (perhaps in .net too) , primitives are stored on stacks , where as reference types are stored on heaps.
No. It does not depend on whether its a primitive or a reference. It depends on the scope whether the stack or the heap is used. Local variables are allocated on the stack, member variables are allocated on the heap when the object is instantiated.
See also Do Java primitives go on the Stack or the Heap?
My question was that I do not understand the proc/cons for this behavior.
Data stored on the stack only lives as long as your method is executing. Once the method is done, all data allocated on the stack is removed.
Data stored on the heap lives as long as it is not discarded (which, in case of Java, is done in the background by the garbage collector). In other languages as C/C++, you explicitly need to delete/free data which was allocated on the heap.
Consider the following code snippet:
String someMethod() {
int i = 0;
String result = "Hello";
i = i + 5;
return result;
}
Here, a primitive (int i) is created on the stack and some calculation is done on it. Once the method finishes, i cannot be accessed anymore, and its value is lost. The same is basically true for the result reference: the reference is allocated on the stack, but the Object (a String object in this case) is allocated on the Heap. By returning the reference as return value, the object it references can still be used outside the method.
You can't generally store reference types on stack because the stack frame is destroyed upon method return. If you saved a reference to an object so it can be dereferenced after the method completes, you'd be dereferencing a non-existent stack location.
The HotSpot JVM can perform escape analysis and, if it determines that an object cannot possibly escape the method scope, it will in fact allocate it on the stack.
where as reference types are stored on heaps.
I don't know what exactly you mean by that part, but remember that, only objects are stored on heap, whereas, references pointing to those objects are still on the stack. Probably this was the doubt you had.
Now, you should also note that, only local variables are stored on stack, whereas instance / member variables are stored on Heap.
For e.g.: -
String str = new String("Rohit"); // Local variable
In above case, str reference will be allocated memory on stack, if of course it is defined in some local scope. And it will point to a new string object created on Heap.
Why can't we reference a memory location inside our stacks instead?
You can but think of this decision as Memory Architecture decision.
By concept, ideally, any data can't be retrieved from stack if it is not on top of it. But in real world you require some location to be accessed from anywhere in the program. So, it can't be stack. and they named it heap.
This link may throw more light on it.
I understand that variables of a method are stored in stack and class variables are stored in heap. Then where does the classes and objects we create get stored in Java?
Runtime data area in JVM can be divided as below,
Method Area : Storage area for compiled class files. (One per JVM instance)
Heap : Storage area for Objects. (One per JVM instance)
Java stack: Storage area for local variables, results of intermediate operations. (One per thread)
PC Register : Stores the address of the next instruction to be executed if the next instruction is native method then the value in pc register will be undefined. (One per thread)
Native method stacks : Helps in executing native methods (methods written in languages other than Java). (One per thread)
Following are points you need to consider about memory allocation in Java.
Note:
Object and Object references are different things.
There is new keyword in Java used very often to create a new object. But what new does is allocate memory for the object of class you are making and returns a reference. That means, whenever you create an object as static or local, it gets stored in heap.
All the class variable primitive or object references (which is just a pointer to location where object is stored i.e. heap) are also stored in heap.
Classes loaded by ClassLoader and static variables and static object references are stored in a special location in heap which permanent generation.
Local primitive variables, local object references and method parameters are stored in stack.
Local Functions (methods) are stored in stack but static functions (methods) goes in permanent storage.
All the information related to a class like name of the class, object arrays associated with the class, internal objects used by JVM (like Java/Lang/Object) and optimization information goes into the Permanent Generation area.
To understand stack, heap, data you should read about Processes and Process Control Block in Operating Systems.
All objects in Java are stored on the heap. The "variables" that hold references to them can be on the stack or they can be contained in other objects (then they are not really variables, but fields), which puts them on the heap also.
The Class objects that define Classes are also heap objects. They contain the bytecode that makes up the class (loaded from the class files), and metadata calculated from that.
The Stack section of memory contains methods, local variables and reference variables.
The Heap section contains Objects (may also contain reference variables).
after short google, I found a link to describe it, yes a youtube video link. ^_^
http://www.youtube.com/watch?v=VQ4eZw6eVtQ
The concept is quite simple :
Instance variables (primitive, Wrapper classes, references, objects (non-static)) - Heap
Local Variables , references - stack
Other data objects like : Class metadata, JVM code, static variables, static object references, static functions etc which earlier used to be in Permgen Space (till Java 7) are now being moved to Metaspace in JAVA 8.
PS : Metaspace is part of native memory, so no need to worry about OOM:Pergem Exeption now.
For more details : https://siddharthnawani.blogspot.com/
Local variables(method variables) + methods live on the stack. While Objects and their instance variable live on the heap.
Now, Reference variable can be local variable(if created inside method) or instance variable(if created inside class, but outside method). So reference variable can be anywhere, either stack or heap.
According to JVM Specification,
The classes and it's own constant pool, i.e static variables are stored in Method Area.
Here class means nothing but bunch of fields, methods and constants, these methods are in the form of instructions are stored in Method Area and can be identified by an address.
Objects are nothing but a filled class template that will be created in Heap Area, but the object reference is created in Stack.
public class Sample{
int field;
static int constant;
public void test(){
int localVariable=10;
Sample samp=new Sample();
}
}
In the example,
sample.class will go to Method Area, that means 'field', 'constant' and method 'test' are allocated in Method Area.
When the execution is started,
The object created by new Sample() will go to Heap but 'samp' is just a object reference which goes to stack and holds the address of object which is present in the Heap
For more information please check this link,
JVM Specification
In Java, a variable can either hold an object reference (s in String s="OOO" holds the reference to the object "OOO") or a primitive value (i in int i=10 holds 10). These variables can either be on the heap or the stack, depending on whether they are local or not and which flavor of the JVM you are using.
In the Java Virtual Machine 8 specification document (https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html), the memory organization pertaining to this is as follows.
Every Java thread has its own JVM stack.
It holds local variables and partial results, and plays a part in
method invocation and return.
There may be object references as well in the stack. The
specification does not differentiate between a primitive variable
and a reference variable as long as it is local. This stack is used using
units of data called frames. However,
Because the Java Virtual Machine stack is never manipulated directly
except to push and pop frames, frames may be heap allocated.
Therefore, it is upto the implementation of the JVM specification (like OpenJDK or Oracle), where the frames are located.
Every JVM instance has a heap. The heap is
... the run-time data area from which memory for all class instances and
arrays is allocated.
The actual memory holding the objects' data resides on the heap. The
heap is shared among all the JVM's threads. This also includes object
references which are part of objects ie instance variables.
For example, take the following classes.
class Moo{
private String string= "hello";
}
class Spoo{
private Moo instanceReferenceVariable = new Moo();
public void poo(){
int localPrimitiveVariable=12;
Set<String> localReferenceVariable = new HashSet<String>();
}
}
Here the object being referred to by the variable instanceReferenceVariable
would be on the heap, and hence all the instance variables of this object, like
string, will also be on the heap. Variables localPrimitiveVariable and
localReferenceVariable will be on the stack.
Method Area: The method area is a restricted part of the heap which
... stores per-class structures such as the run-time constant pool,
field and method data, and the code for methods and constructors,
including the special methods used in class and instance
initialization and interface initialization.
Run-time constant pool: This is a part of the method area.
Hope this was able to clarify things.