Java memory (Stack) allocation for local variables - java

I am learning java and right now
i am stuck at memory allocation of object's and local variables.
can any one illustrate or clear some of my doubts??
I read about Heap and Stack Memory for Object's instance
Variable's and Local Variable's. I have question whether a new
STACK is being created for each method?? or for each class of a
single stack is used by a whole class??
I had read that ONE STACK
is being created by every thread What is means
Thanks
Mahaveer

Every thread has it's own stack.
Whenever you use new, an object is created on the heap.
Local variables are stored on the stack. That includes primitives (such as int) and the references to any objects created. The actual objects themselves aren't created on the stack, as I mentioned when you use new they'll be created on the heap.
I have question that weather a new STACK is being created for each
method??
The same stack is being used when a method is called. A method will create it's own little section on the stack called a "stack frame" that's used to hold it's local variables.
It's just like a stack of plates, when a method is called a plate is added to the top of the stack (a stack frame), and when that method ends the plate is removed from the stack. All of that method's local variables will be destroyed with it, but the actual objects created with new won't.
The JVM's garbage collector will look after destroying objects on the heap (the one's created with new) when it sees you no longer need them.

Each thread has a private stack.
Each method has a private stack frame within that thread's stack.
Stacks are associated with thread in a one-to-one mapping. Stacks are absolutely not associated with methods and classes.
The way to reason about all this is that the local variables of a method are private to each invocation of that method.

Ofcourse, java garbage collector always takes care of the Heap, when it gets a chance to be executed, so it only looks for orphan objects and wipes them out, that's why NEW keyword in java always creates new objects on the Heap memory.

Related

How Java manages variables in memory

Let's say I have this code:
{
int var = 2;
// more code
}
What happens with 'var' after the code is executed and it is not used anymore? Is it deleted from memory or it stays there occupying memory, or something else?
Related to this, is it better to work with variables that way^, or to make some global variable and just change it's value?
Local variables live on the stack. If it's a reference to an object then only variable is on the stack.
Instance variables live on the heap because they belong to an object.
Also this post (Stack and heap memory in java) might be helpful.
To make a long story short, in java (and other JVM languages), you don't have to care about memory allocation and dealocation at all. You really shouldn't be worrying about it. Once you lose the reference to that variable (in this case, when the method call ends), the variable is effectively gone. Some indefinite amount of time after that, the Garbage collecting thread will notice that you can't possibly access that variable anymore, and free up the memory it was using.
See: Garbage Collection in Java.
if you are defining any variable as instance variable then that variable will be used by instance. and instance will be saved in Heap memory area.
Garbage collector will run periodically to clean non referenced object from memory.
but if that variable is defined inside any block or method then that will be stored Stack memory.
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. Stack memory is always referenced in LIFO (Last-In-First-Out) order. Whenever a method is invoked, a new block is created in the stack memory for the method to hold local primitive values and reference to other objects in the method. As soon as method ends, the block becomes unused and become available for next method.
Everything in Java is removed from memory when it is no longer referenced. It takes a lot of effort to cause true memory leaks in Java.
Java primitives like int, boolean, and char are put on the stack and removed from memory as soon as they leave scope. Java objects like String, arrays, or ArrayList are allocated on the heap (and referenced by the local variable on the stack). Objects are garbage collected (removed from memory) when there is no longer a reference to them.Static variables belong to a class and will be a reference an object as long as the class is loaded, which is usually the entire run time of the Java program. Statics are the closest thing Java has to global variables, but overuse or misuse of statics is actually a way to cause memory issues rather than solve them.

What happens to the stack when exiting a method?

I was reading What and where are the stack and heap?. One thing I am a bit fuzzy on is what happens to the stack after a method exits. Take this image for example:
The stack is cleared upon exiting the method, but what does that mean? Is the pointer at the stack just moved back to the start of the stack making it empty? I hope this is not too broad of a question. I am not really sure what is going on behind the scenes when the stack is cleared from exiting a method.
When a method is called, local variables are located on the stack.
Object references are also stored on the stack, corresponding objects are store in the heap.
The stack is just a region of memory, it has a start and end address.
The JVM (java virtual machine) has a register which points to the current top of the stack (stack pointer). If a new method is called, an offset will be added to the register to get new space on the stack.
When a method call is over, the stack pointer will be decreased by this offset, this frees the allocated space.
Local variables and other stuff (like return address, parameters...) may still on the stack and will be overwritten by next method call.
BTW: this is why java stored all objects in heap. When an object would be located on the stack, and you would return the reference which points to the stack, the object could be destroyed by next method call.
During execution of a function, all local variables are created in the stack. That means that the stack grows to make enough room for those variables.
When the function ends, all the local variables goes out of scope and the stack is rewinded. Nothing else needs to happen, no implicit zeroing memory. But :
semantically the variables go out of scope and can no longer be used
in the hard way, the stack pointer is rewinded, effectively freeing the memory : it will be useable by next function call
Above is not only true for functions but can be the same for any block of code since semantically the variables defined in the block go out of scope at end of block.
Is the pointer at the stack just moved back to the start of the stack making it empty?
the pointer at the stack is moved back to where it was before the function call. The stack would not be empty because it contains data that belongs to calls that brought the program to that point.
To illustrate: if func1 called func2 called func3 the stack will look something like this:
func1 args/local vars... | func2 args/local vars... | func3 args/local vars...
After func3 returns it will be:
func1 args/local vars... | func2 args/local vars...
A stack is just that, a stack of things, usually a stack of frames, with the frames containing parameters, local variables and instances of objects, and some other things depending on your operating system.
If you have instantiated objects on the stack, i.e. MyClass x and not MyClass * x = new MyClass(), then the object x will be torn down and its destructor called when the stack is rewound to the previous frame, which essentially just makes the current stack pointer(internal) point to the previous frame. In most native languages no memory will be cleared, etc.
Finally this is why you should initialise local variables(in most languages) as a call to the next function will setup a new frame which will most likely be in the same place as the previously rewound stack frame, so your local variables will contain garbage.
It might be useful for you to think about what your compiled code might look like at a machine (or, better for us humans, assembly) level. Consider this as a possible example in X86 Assembly:
When the method is called, arguments will either be passed in the registers or passed on the stack itself. Either way, the code calling the method will eventually:
call the_method
When this happens, the current instruction pointer is pushed onto the stack. The stack pointer is pointing at it. Now we're in the function:
the_method:
push ebp
mov ebp, esp
The current base pointer is preserved on the stack and the base pointer is then used to reference things in the stack (like passed in variables).
sub esp, 8
Next, 8 bytes (assuming two four byte integers are allocated) are allocated on the stack.
mov [ebp-4], 4
mov [ebp-8], 2
The local variables are assigned. This could actually be accomplished by simply pushing them but more likely there will be a sub involved. Fast forward to the end:
mov esp, ebp
pop ebp
ret
When this happens, the stack pointer is right back where it was when we started, pointing at the stored base pointer (saved frame pointer). This is popped back into EBP leaving ESP pointing at the return pointer which is then "popped" into EIP with the ret. Effectively, the stack has unwound. Even though the actual memory locations haven't changed for the two local variables, they are effectively above the stack (physically below in memory, but I think you get what I mean.)
Keep in mind the stack is a zone in memory assigned to a process.
In summary, when in your code you call a function (tipically in assembly language), you need to store in memory the registers you're going to use (it could vary if you're following another contract) because these registers could be overwriten by calls to another function (you'd need to the store return address, arguments, and a lot more, but let's omite that). To do that you decrease the stack pointer by that number of registers. Before to exit, you need to make sure you increase the stack pointer by that same number. You don't need to do anything more because the values you were storing are not needed anymore, they will be overwrited by the next function call.
In Java, references to objects are in the stack when the object itself is in the heap. If all the references to an object are removed from the stack, the garbage collector will remove the object from heap.
I hope my answer helps you. Also, check this.

Explain the difference between contiguous allocation (memory held in a heap in the stack) vs. memory in a heap [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Explain the difference between contiguous allocation (memory held in a heap in the stack) vs. memory in a heap.
I'm new at this and not entirely sure.
The question isn't contiguous versus heap, but automatic versus heap.
Automatic storage is set up on entry to a block of code -- traditionally on entry to a function or method -- and discarded when that function returns, so its memory space on the stack can be reused by the next function call. That's how most local variables are handled. Obviously this isn't useful for anything which is intended to persist past the end of that function call.
In Java, objects are never allocated from automatic storage. Instead, they are allocated from the heap, on demands, when the new operation is performed. There are several reasons for this which, frankly, unless you're designing a programming language you don't really need to know about and it's too large a topic to cover here. The important thing is that since they were obtained from the heap, their lifetime is independent of the stack frame. Since Java is a garbage-collected language, their memory will be automatically recovered for reuse sometime after that last reference to them goes away -- again, the details are too large a topic to cover here, but basically you can trust that the GC comes through periodically to pick up the clothes we dropped on the floor and toss them into the laundry.
A stack frame only exists for the life of a method call, which means that memory is allocated to provide storage for all your local variables and method parameters that are used in some way that assist helping the method achieve its goals of whatever task it set out to achieve.
Examples of memory storage in a stack frame are temporary pointers that are used to keep track of an index position in an array which you are iterating through. Once the loop is finished, the stack frame would be popped off the stack, which means all the temporary memory allocated for the local variables and method parameters that existed are released back into the system.
The heap is different because it is where objects live, not "pointers" to objects.
When I was learning I found it hard to work out the difference between the two.
The key point that helped me was that, a pointer to an object is kept in a stack frame, it has a little bit of temporary memory allocated that exists for the life time of the method call. Thus, you can only access an object when the method is in "scope".
The pointer contains a memory address that leads to the location of the object stored on the heap. This allows you to reference the object to change the objects state at a later time.
public static void main(String[] args)
{
Person person = new Person("Steven", 30);
}
When you run this program:
new keyword means java will allocate memory on the heap for the space required to store the Person objects instance variables.
The important part to understand is, no memory is required to store an objects methods. When a method is called, a new stack frame is created which allocates temporary memory for the duration of the method call. Using the example above, a Person has 2 instance variables, a String name and int age. This means that the memory required for this Person object is the required memory to store a reference variable of type String (bit pattern of the memory address of a String object on the heap) and memory to hold the bit pattern of an int.
Lastly, the main method is a stack frame too, so when main finishes, you no longer have a reference to a Person object or access to any temporary variables that may have existed in main.
This is true for any method, if you have a method that creates an object but doesn't return the reference to that object, then you can never access the object and the java garbage collector comes along at a later time and cleans up all the objects on the heap that don't have references pointing to them.
If you are starting out, I highly recommend head first java. It is a great book IMO and covers these topics in easy to understand ways.
When we talk about memory or disc allocation, the word "contiguous" simply means "without any gaps".
A single stack or heap memory allocation is always contiguous ... in every programming language runtime I've ever encountered where it makes sense to talk about allocations at all.
A sequence of allocations is contiguous if there is no gap between the individual allocations.
This is orthogonal to stack versus heap. Both stack allocations and heap allocations can be contiguous ... or non-contiguous.
Well ... not quite orthogonal.
If you are talking about strictly contiguous memory addresses (physical or virtual), a typical heap node consists of the area of memory that the application can use, plus a small node header. So, if you look at the available memory for two consecutive heap nodes, there is a gap ... comprising the node header ... that prevents the two regions being used by the application as a single contiguous region. (And you'd better not try 'cos if you overwrite the node header, bad things could happen.)
However, when we are talking about Java this is not relevant. Java does not allow an application to join objects or arrays together. (That would be a fundamental violation of runtime type safety.) So the notional gap in the address ranges doesn't matter. In the Java context, we would say that two objects are contiguous, ignoring the heap node / object header.
Besides, in Java you can't explicitly allocate things on the heap either. In a classical JVM, only local variables comprising primitive types and references go on the stack. There is no way to say "allocate this array on the stack". (The JVM might do the latter under certain circumstances, but it is entirely transparent to the application, and certainly not something that you could make use of.)

What occurs when object is created in Java?

My teacher gave me a question:
"What occurs when objects are created in Java".
To the best of my knowledge, memory allocation, variable initialization and constructor method invocation happen when an object is created.
But my teacher said that I was almost right. The 2 later things are right, except memory heap. Instead, he said the memory allocation occurs. I think that object is stored in heap, so my teacher is wrong. Do you think so?
As always, the best place to find a solution for these kinds of questions is in the Java Language Specification.
Specifically, from the section on new instance creation, it can be understood that this is the sequence when a new object is created, as long as no exceptions occur:
Memory is allocated.
Fields are initialized to their default values.
The "first line" of the chosen constructor is invoked, unless it's an Object. By first line I mean either explicit call to super() or this(), or an implicit call to super().
The instance initializer is executed and the fields are initialized to their requested values (actually field initialization is usually compiled as an inline part of the instance initializer).
The rest of the constructor code is executed.
Now, it is possible that your teacher is talking about memory allocation as an actual operating system call - and in that case he's right in the sense that the JVM manages its own heap and thus a Java memory allocation does not necessarily translate to an OS memory allocation call (although it may).
I'll answer that using a simple example.
Say you have a class Car. Now you write:
Car car;
car = new Car();
The first statement creates a reference with car in the stack.
In the second statement, the Car class will be loaded to the main memory, then it will allocate memory for the members of Car in the heap. When this happens, the members will be initialized with values provided by the JVM.
While the JVM is running the program, whenever a new object is created, the JVM reserves as portion of the Heap for that object (where the object will be stored). The amount of Heap that gets reserved is based on the size of the object.
The JVM maps out this segment in the Heap to represent all of the attributes of the object being stored. A reference (address in Heap) to the object is kept by the JVM and stored in a table that allows the JVM to keep track of all the objects that have been allocated on the Heap. The JVM uses these references to access the objects later (when the program accesses the object).
On top of what other people have said, if this is the first use of the object then its Class must be initialised -as described in the JLS (the section before the one on new instance creation!).
This basically involves loading into memory the necessary information about the class i.e. creating a Klass object for the static variables and method table to live. This may also involve loading super classes and interfaces. This is all carried out by the ClassLoader.
When object is created in java then these 6 step will be happens one by one---
1.JVM allocates 8 bytes of memory for the reference variable & assign default value as null.
JVM will verify whether class loading is done or not,if class is already loaded then it will ignore or else it will perform class loading.
At the time of class loading ,if any static variable are there then it will allocating memory.
By using new operator,object memory will e created inside heap memory.
At the time of object creation,if any instance variables are there then those will allocate memory inside object Memory.
It will assign object memory address to the reference variable which is created first.

Object is storage and removal from heap memory

Can anybody explain to me how objects are stored and removed from heap memory of Java. I'm looking for more information than simply:
an Object will removed when there is no reference
For example:
class Heap
{
void add(int a, int b)
{
System.out.println(a+b);
}
public static void main(String ar[])
{
Heap obj=new Heap();
obj.add(4,3);
obj.add(5,5);
}
}
Here how is obj and a, `bJ allocated in java memory. When will it be removed from memory by the JVM?
Put simply:
obj is allocated on the heap when new Heap() is invoked.
a and b both are allocated on the stack (primitive types, method arguments), the memory will be released upon returning from add.
obj will be removed from the heap whenever the garbage collector runs after the execution is out of main (the specification does not guarantee the GC will at any given time, it'll figure out when's the right time on its own, although almost-full-heap is probably a very common trigger) - in this case though, since the program would terminate, it would be immediately after returning from main.
The Heap object will be create inside heap. that will contain the methods inside the class and member variables.
when you call a method, that will be loaded inside stack and will be discarded automatically by jvm after executing that method.
Stack section of memory contains methods, local variables and reference variables.
Heap section contains Objects (may also contain reference variables).
Well... a and b aren't allocated on the heap at all.
They are on the stack for passing into the function. As soon as the execution leaves add(), the variables a and b cannot be used anymore and will be removed by the jvm.
When you run your program:
Before the main method is executed, the JVM will allocate a new thread of execution for you, this thread (called the main thread) will have a stack associated with it, the stack is a place where local variables and temporary data is placed.
Within the stack a new frame will be associated with the main method.
The obj reference will be created in the main method stack frame.
When you invoke the new Heap() the JVM will attempt to allocate memory for your object in the heap memory area. If successful, it will assign an object reference to your local variable, if it fails, it may attempt to make room for your object running the garbage collector, if still fails to find enough room for it an OutOfMemoryError is thrown.
When you invoke the add(int, int) method on your memory reference, the JVM will first dereference the pointer to gain access to the actual object in the heap, if it fails a NullPointerException will be thrown, otherwise it will look for the method to be executed in what is called the method area (an area of memory where class information is located).
If the method is found, a new frame is created in the in the stack of the currently executing thread, and the control of execution is transferred to the new method.
Two variables are placed in the method stack frame a and b and they are initialized with copies of the values you passed as arguments (i.e. 4, 3).
The method does what it does, and when it is done the current stack frame is destroyed, and control of execution returns to the previous frame.
Since you invoke the method add again, the process is repeated.
The main method ends, its stack frame is removed. Now the obj reference is lost and there is no longer a way to reach to your object in the heap. The object it was pointing to is now illegible for garbage collection.
The JVM process is terminated and all related resources are freed. Probably in this scenario, the garbage collection actually never run, but if it did, the memory occupied by your object in the heap would be reclaimed.

Categories