Why do we use Heap Memory, Can we use Stack memory for the same?
EDITED
One more question came in my mind after reading answers
1) is there any other kind of memory which we can think of alternative to Heap and Stack?
Edited
I came across the string pool, is that memory associated with the heap or Stack?
Well, you have to use the heap if you want to use objects. Objects are inherently pointers on the stack (or inside other objects) to memory chunks in the heap.
Unlike C++ where you can put objects on the stack or heap, Java does things differently.
Even in C++, it's a good idea to use the heap for objects that must outlive the function they were created in. You probably can avoid it but you may find yourself with a performance problem with all the copy constructors.
As to your edit:
Is there any other kind of memory which we can think of alternative to Heap and Stack?
Sure there is: Static data members, the ones where there's only one per class rather than one per instantiated object must go somewhere. These can't be on the stack since they may disappear when you exit from a function. And they can't belong to an particular object.
These (at least in the Sun/Oracle JVM) go into the Method area.
In addition, you should not think of there being one stack. Every thread gets its own stack on creation.
There's also the runtime constant pool and stacks for native (non-Java) calls.
There's lots of information on the JVM internals here regarding that aspect but keep in mind there may be a distinction between the logical machine and the implementation.
Heap memory is central to Java. All objects are allocated on the heap, and local variables hold only references (essentially pointers) to them. C# allows you to have objects (value types) that live on the stack. Java chose not to borrow this from C++, partly in order to simplify the language.
Across languages, heap memory is the way to provide long-lived objects of arbitrary size.
Can we use Stack memory for the same?
Basically no.
In Java, stack memory is used solely for parameters and local variables of methods (and some hidden book-keeping info which is not relevant to this discussion). And for those variables, only primitive types use just stack memory. Any object or array is represented as a reference to something on the heap, and Java provides no way to allocate an object or array on the stack.
[Aside: it is theoretically possible to perform any calculation in Java using just primitive types and recursive static methods. However, it would be horribly messy. Even writing a simple message to the console will entail your application causing objects to be allocated on the heap. So we can dismiss this as being totally impractical.]
In the JVM, instead of a thread local stack for objects it uses a Thread Local Allocation Buffer or (TLAB) This gives much of the performance benifits of a Stack, without the developer needing to worry about wether an object is on the stack or not.
Heap memory is used to store objects in Java. No matter, where object is created in code.
e.g. as member variable, local variable or class variable, they are always created inside heap space in Java.
If there is no memory left in stack for storing function call or local variable, JVM will throw java.lang.StackOverFlowError,
While if there is no more heap space for creating object, JVM will throw
java.lang.OutOfMemoryError Java Heap Space.
Another important factor to consider is scoping. If all objects were to be allocated on stack then they go out of context as stack frame gets rolled out. In layman terms, think of stack as a dump that stores all the variable values and object references that are local to a subroutine/method which is currently in scope. As soon as it finishes executing (or the method goes out of scope), then all in it would be lost.
It makes it easier for compiler to manage large &/or dynamic sized variables too- they still take small constant storage on call stack- that of 4 bytes ( a heap pointer).
Related
Would the data in the following statement be stored as automatic memory allocation, or dynamic memory allocation or both
myFunction(new MyClass());
Thank You!
The terms “automatic memory allocation” and “dynamic memory allocation” make no sense in the context of Java. In Java, all memory is managed by the execution environment.
In other programming languages, the terms “automatic storage” and “dynamic storage” are used to distinguish between storage, which is automatically deallocated when going out of scope, and storage, which requires an explicit deallocation action performed by the application. In Java, there are no explicit deallocations at all. You will find that people and literature continue to distinguish between stack and heap, where only the latter contains objects, whose lifetime may exceed the execution of the method in which they were created. This, however, is only a logical separation, which might not reflect how a particular JVM implementation actually works.
The Java® Language Specification doesn’t mandate much details about the workings of this. There are only two spots at all:
15.12.4.5. Create Frame, Synchronize, Transfer Control
A method m in some class S has been identified as the one to be invoked.
Now a new activation frame is created, containing the target reference (if any) and the argument values (if any), as well as enough space for the local variables and stack for the method to be invoked and any other bookkeeping information that may be required by the implementation (stack pointer, program counter, reference to previous activation frame, and the like). If there is not sufficient memory available to create such an activation frame, a StackOverflowError is thrown.
17.4.1. Shared Variables
Memory that can be shared between threads is called shared memory or heap memory.
All instance fields, static fields, and array elements are stored in heap memory. In this chapter, we use the term variable to refer to both fields and array elements.
Local variables (§14.4), formal method parameters (§8.4.1), and exception handler parameters (§14.20) are never shared between threads and are unaffected by the memory model.
Note that this is the only place where the term “heap” is used as memory type and how it’s actually defined here…
The sections §15.9.4. Run-Time Evaluation of Class Instance Creation Expressions and §15.10.2. Run-Time Evaluation of Array Creation Expressions are much more vague, saying that “space is allocated” and an OutOfMemoryError is thrown if not enough space is available, and nothing more.
So if you go the route of distinguishing between stack and heap, you can say that your code myFunction(new MyClass()); will cause a heap allocation for an instance of MyClass, followed by a stack allocation for the activation frame of the actual implementation of the myFunction method. Not that it matters for any practical purpose.
If you want to dig more into the way, JVMs may implement it, you may refer to the Java® Virtual Machine Specification instead:
2.5.2. Java Virtual Machine Stacks
Each Java Virtual Machine thread has a private Java Virtual Machine stack, created at the same time as the thread. A Java Virtual Machine stack stores frames (§2.6). A Java Virtual Machine stack is analogous to the stack of a conventional language such as C: it holds local variables and partial results, and plays a part in method invocation and return. Because the Java Virtual Machine stack is never manipulated directly except to push and pop frames, frames may be heap allocated. The memory for a Java Virtual Machine stack does not need to be contiguous.
2.5.3. Heap
The Java Virtual Machine has a heap that is shared among all Java Virtual Machine threads. The heap is the run-time data area from which memory for all class instances and arrays is allocated.
The heap is created on virtual machine start-up. Heap storage for objects is reclaimed by an automatic storage management system (known as a garbage collector); objects are never explicitly deallocated. The Java Virtual Machine assumes no particular type of automatic storage management system, and the storage management technique may be chosen according to the implementor's system requirements. The heap may be of a fixed size or may be expanded as required by the computation and may be contracted if a larger heap becomes unnecessary. The memory for the heap does not need to be contiguous
Note, how these definitions only differ in their purpose while not having significant difference in their constraints, i.e. might be fixed-size or resizable and might be contiguous or not, not to speak of the explicit mentioning of the possibility to allocate stack frames on the heap.
There are three groups of memory in Java
Heap - this is where Objects are created and located when you call new MyClass();
Stack - The stack contains stack frames, and stack frames have space allocated for primitives and pointers to Objects in the Heap. Stack frames are allocated on method call and deallocated on method return
String constants: String literals defined at compile time will be added to a String constant pool. At runtime, it is possible to add strings to the pool using String.intern()
That's it
There are two things being allocated in your example;
The expression, new MyClass() allocates an instance of MyClass on the object heap.
The result of the new expression is an object reference. The object reference is saved in the activation record for a call to myFunction(). Activation records are allocated on the calling thread's call stack.
When you create a new object, it often allocated on the heap however with escape analysis, it can be unpacked onto the stack as if it was a local variable.
The only allocation is via new or a capturing lambda (or some native method in rare cases) There isn't any explicit distinction between different ways of allocating an object.
I have a question regarding dynamic memory allocation.
When it comes to C, memory is allocated using the functions malloc(), calloc() and realloc() and de-allocated using free().
However in objected oriented languages like C++,C# and Java, memory is dynamically allocated using the new and deallocated using delete keywords (operators) in case of C++.
My question is, why are there operators instead of functions for these objected oriented languages for dynamic memory allocation? Even when using new, finally a pointer is returned to the class object reference during allocation, just like a function.
Is this done only to simplify the syntax? Or is there a more profound reason?
In C, the memory allocation functions are just that. They allocate memory. Nothing else. And you have to remember to release that memory when done.
In the OO languages (C++, C#, Java, ...), a new operator will allocate memory, but it will also call the object constructor, which is a special method for initializing the object.
As you can see, that is semantically a totally different thing. The new operator is not just simpler syntax, it's actually different from plain memory allocation.
In C++, you still have to remember to release that memory when done.
In C# and Java, that will be handled for you by the Garbage Collector.
I believe it's done solely to simplify the syntax as you've said.
Operators are simply another way to call methods (or functions).
using "12 + 13" is no different than using Add(12, 13).
A way to see this is via the operator overrides in C# for example:
// Sample from - https://msdn.microsoft.com/en-us/library/8edha89s.aspx
public static Complex operator +(Complex c1, Complex c2)
{
Return new Complex(c1.real + c2.real, c1.imaginary + c2.imaginary);
}
It's a regular method but allows the usage of operators over complex classes.
I'm using the Add operator as an example since I see it as no different than the memory allocation operators such as "new".
The whole point of Object Oriented design/programming is to provide meaningful abstractions.
When you are doing good OO design; you do not think (immediately) on areas in memory. One thinks about of objects; that carry state and provide behavior.
Even when writing code in C++, in most cases, I don't have to worry about subtleties like "why will my bits be aligned", "how much memory does one of my objects required at runtime" and so on. Of course, these questions are relevant in certain situations; but within OO design; the true value comes from creating useful abstractions that help to solve "whatever domain" problems as precise, easy, maintainable, ... as possible.
For the "keyword" versus "function" thing: just have a look at Java. The fathers of the language simply didn't want Java programmers start thinking about "memory pointers". You only deal with objects; and references to objects. Thus, the concept of "allocating" memory, and getting back a "pointer" simply does not exist at all here. So, how would you then provide this functionality as library method?! Well, if you would like to: you can't.
Finally, to a certain degree, this is a matter of "taste/style" by the people designing the language. Sometimes people prefer a small language core; and do everything in libraries; and other people prefer to have "more" things built-in.
The new keyword is ideed to simplify the syntax, which is pretty suggestive and also does more than memory allocation, it invokes the constructor(s) also.
One thing you have said:
C++,C# and Java, memory is dynamically allocated and de-allocated using the new and delete keywords (operators)
for Java and C# it is only the new keyword, there is no delete. I know that in C# you are able to use using blocks to ensure that the resource will be released when the object is not used anymore, but this does not involves memory deallocation in every case, such as it's calling the Dispose method.
One more thing which needs to be pointed is that the goal of an object oriented programming language, as GhostCat just said, is to release the programmer to think of how memory is allocated in most of the cases, and more important, how are the objects released, this is why garbage collector was introduced.
The main principle is that as the programming language is higher, it has to abstract such things as memory management, and provide easy ways to solve the actual business problems one is looking for. Of course this might been considered when a programming langage is chosed for a specific task.
C :malloc calloc are basically the only ways in C to allocate memory.
malloc : it allocate uninitialized memory according to requested size without initializing it to any value
calloc : almost same as malloc ,plus it also initialize it to zero(0).
In both cases , you required something :
The requested memory size for allocation should be given at the time of initialization and it can be increase with realloc.
The allocated memory need to be deleted with free ,sometimes it can be result in a OOM error if somebody don't have a good memory to free the allocated memory although free is quite handy when you are doing lot of memory extensive work.
NOTE : Casting and size(to allocate memory) is required with malloc and calloc
C++: C++ also has malloc and calloc (free and reallocate too) along new and delete ,new and delete can think of as a modern way to allocate and free memory but not all of the OOP's based language have both. e.g java don't have delete.
new uses constructors to initialize default value so it's pretty useful while working with objects when you have various scenarios to set initial value using parameterize ,default or copy constructors.
NOTE : With new you don't have to do the appropriate casing unlike with malloc and calloc and no need to give a memory size for allocation. one less thing , right.
delete is used to release the memory, the delete call on some object also calls destructor which is the last place of the life-cycle of that object where you can do some farewell tasks like saving current state etc and then memory will be released .
Note : In C# and java the deallocation of memory is handled by Garbage-Collector who does the memory management to release the memory.It used various algos like mark-sweep to release the memory if there is no reference variable pointing to that memory or the reference variable value is set as null.
This may also lead to memory leak if there is a reference variable pointing to that object in memory which is no longer required.
The downside of GC is, this makes things slow
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 7 years ago.
Improve this question
I am taking some classes and object lessons in Java having C++ background. I want to know the reason why we cannot choose the objects to be declared on the stack memory? Why must everything go on the heap except for the primitive types?
Here's something to clarify what I was asking.
Essentially, if we have:
Scanner input = new Scanner(System.in);
Then why cannot we have it on stack in the first place?
One of the strongest attractors of the original Java design (in mid-1990s) was simplicity. Supporting heap-based objects is essential, whereas stack-based ones are an optimization. Java is not alone here: many languages take that approach (LISP, Haskell, JavaScript, Ruby, etc.). Stack-based allocation does happen in Java, but only as an internal optimization trick and not something that the user can control.
Especially keep in mind that there is an essential difference in how a pointer to an object passed to a function ("a reference passed to a method" in Java-speak) can be treated by the callee: it is not allowed to retain the pointer if it's stack-based. This alone creates huge complications and bug opportunities.
Finally, stack-based objects bring much less to a garbage-collected language than to manually-managed languages like C and C++.
The data on the stack, say a C struct, disappears after the function call has returned. Hence one would need copying and correction of pointers.
Think of the hidden extra functionality needed here:
struct S* f() {
struct S s = ...;
g(&s);
return &s;
}
Java was meant as simplification, having its own management of memory, and doing things immediately on the heap seemed more direct, less convoluted.
This in view of C++, with its copy constructors, pointers and aliases.
Java does not allow explicit on stack allocation of objects. The language is not competing with low level languages such as C, and the creators of the language made this choice as a simplification.
However times change, and Java has grown since its humble beginnings. As the JVM becomes more sophisticated, automatic allocation of objects to the stack has become possible. The rationale for this is similar to the 'register' keyword in C; let the compiler manage the low level detail. It has become better at doing it than humans. In Java automatic allocation of objects onto the stack has been hampered by two factors, firstly the Sun/Oracle JVM is very old and very complex now. It is difficult to change, and Oracle has been careful about preventing backwards breaks. Secondly, so far their work on stack allocations has not yielded the large benefits that were expected. It did improve some situations, but the JVM has its own trade offs and behaviours. So this comes down to a question of time/pay-off and priorities. I believe that work to improve the benefits of automatic allocation continues behind the scenes; but there are no plans to make it explicit.
To put it simple, the key advantage of objects on stack is that the memory is automatically managed for you. When function puts objects on stack, they are cleaned from memory on function exit.
Since java already has automated garbage collection, this key advantage doesn't bring that much.
Sure there is a speed of access performance price that you might pay by being unable to allocate objects on stack directly, but as Marko mentioned, there are internal optimizations that might do just that.
Why must everything go on the heap except for the primitive types?
This statement is not accurate. Primitive types can go on the heap as well if they are part of a class instance. A local variable is stored on the stack, where as class variables are on the heap.
As for why objects are stored on the heap. It's after all a design decision. One reason is that it is a managed area in the JVM that is subject to garbage collection. As a managed area in the JVM, it may be organized in generations and may grow or shrink in size. See this section from the JVM specification:
The Java Virtual Machine has a heap that is shared among all Java Virtual Machine threads. The heap is the run-time data area from which memory for all class instances and arrays is allocated.
The heap is created on virtual machine start-up. Heap storage for objects is reclaimed by an automatic storage management system (known as a garbage collector); objects are never explicitly deallocated.
If I create a static variable in Java, does it automatically go into the perm gen space on the heap? it seems obvious that the answer is yes, but i cannot find the confirmation anywhere.
I know the static variable (also strings and enums) are alive for the life of the JVM so it must go on the permanent heap. IS this correct?
The idea of the "PermGen" is completely implementation-dependent, and JVMs are free to handle the "physical" memory management however makes sense to them--they're not even actually required to provide garbage collection!
The PermGen is just a feature of some JVM implementations (including the Sun/Oracle HotSpot JVM for many years), and it's actually being eliminated with a new approach in the Oracle Java 8 JVM. It's quite likely that JVMs that include the concept of a PermGen will put static variables there for performance, but it's entirely up to the programmer.
JLS #17.4.1 Shared Variables
Memory that can be shared between threads is called shared memory or heap memory.
All instance fields, static fields and array elements are stored in heap memory. In this chapter, we use the term variable to refer to both fields and array elements. Local variables (§14.4), formal method parameters (§8.4.1) or exception handler parameters are never shared between threads and are unaffected by the memory model.
Nice description here By #Stephen:static allocation in java - heap, stack and permanent generation
I am trying to fully understand how the Java works with its memory arrangement. The discussions on Internet are very confused, and sometimes contradicts each other, so I found no one I can trust. This thing can be very complicate if it mixed with static, static method, local variable, thread, volatile and so on. So I am thinking if there is a way I can study that myself my doing some Java coding experiment. A class MemoryTrack does something like this,
public myMethod(){
int i = 0;
MemoryTrack.show(new myClass()); //print out "Heap at address 111"
MemoryTrack.show(new myClass()); //print out "Heap at address 222"
MemoryTrack.show(i); //print out "Stack at address 333"
MemoryTrack.show("a static method"); //print out "stack at address 444"
}
The use of memory is described in Section 2.5 of the Java Virtual Machine Specification. The stack stores stack frames (containing local variables and partial results). The heap is where all class instances and arrays come from. Stack frames can also be allocated from the heap (and then pushed onto the stack). There are also method areas and runtime constant pool memory. The details are spelled out in the spec.
As far as monitoring memory usage, several profilers have tools for that. For monitoring from within the program, take a look at the MemoryMXBean class (and related classes in the java.lang.management package). It's very easy to use. While it probably doesn't give you everything that it sounds like you want, but it's probably the best thing available.
The rule is pretty simple: heap contains objects, stack contains local variables and method parameters. Object fields are inside the objects, in the heap. Don't know about static fields. Methods and constructors are not stored in the stack, nor in the heap. Threads and volatile don't matter.
Method calls are on the stack. Each has a space reserved to it, the stack frame, that contains the local variables and the parameters.
Two things you need to know
its not as complicated as you think.
it doesn't matter 99% of the time.
Variables are always on the stack.
Objects are always on the heap. (There are exceptions but I wouldn't worry about them)
Methods and classes are always in the perm gen.
In the HotSpot/OpenJDK JVM, static fields are collected in a singleton object for the class. You can see the instance if you do a heap dump. Other JVMs may do this differently.
A class MemoryTrack does something like this,
Such a method wouldn't do anything useful as the argument will always be on the stack and object it refers to will always be on the heap. You can't get the memory location of an Object in a standard way and it unlikely to be useful if it did as it can change at any time.
You may think all variables in Java are on heap. Actually it is implementation dependent.