Memory Allocation in JVM - java

I am thinking about memory allocation in Java i.e in which
memory location methods, fields and objects are stored.
Suppose I have 2 classes
import java.util.*;
class ABC
{
int field;
List<Integer>l;
}
class XYZ
{
int x,y,z;
static int p;
void fun(ABC a){
a.field = 10;
a.l = new ArrayList<Integer>(10);
a.l.add(10);
}
}
public class Simulator{
public static void main(String[] arg){
XYZ tmp_1 = new XYZ();
ABC tmp_2 = new ABC();
tmp_1.fun(tmp_2);
System.out.println(tmp_2.l);
}
}
Now where will the memory be allocated for each of the data members,functions and objects be allocated ?
My thoughts are objects, data-members will be stored in Heap but I am not sure about functions and their data members ?

Yes, all objects are allocated on the heap. I.e.: everything created with new will be placed on the heap. All fields of such objects are thus also on the heap.
I suppose you are referring to local variables and parameters in functions. These are placed on the stack (for each call of the function). Note, however, that when function variables/parameters are of reference types then the actual object they point to is on the heap but the variable/parameter itself will be on the stack (similar to a pointer in C/C++). On the other hand, function variables/parameters of primitive types (like int, double, etc.) will be entirely on the stack. A slightly related but relevant to the topic is the concept of boxing.
Functions themselves are static code and are stored in a special part of the memory where all executable code resides. Note that all instances of a class share the same functions (i.e. "new functions" are not created with newly created objects, even if these functions are instance functions). Thus, when you call an instance function on an object, a special this reference is passed to that function (it's an implicit argument to the function). This is how the function knows on which objects it should act.

Here's a breakdown of how the different things that you refer or allude to are stored:
Local variables and method / constructor parameters can contain either primitive values or references to objects or arrays. (They cannot contain the objects or arrays themselves.) Locals and parameters are stored in activation frames (to use the JLS terminology), and these frames are stored on a thread's stack. Thread stacks are non-heap memory in typical JVMs.
Objects and arrays are represented in heap memory.
Instance fields (containing primitive or reference values) are stored in objects, and hence in the heap.
Array elements (either primitive or reference values) and the length of an array are stored in the array and hence in the heap.
Static fields are stored in special frames called static frames. These frames are stored in the heap.
The code of Java methods (in byte-code and native code form) is typically represented by code blocks that are stored in the heap.
Note that the above is based on what happens in a typical JVM. In fact, the Java Language Specification does not mandate that things are stored in a stack or a heap. The terms stack memory and heap memory hardly appear in the JLS at all, and it is conceivable that other memory organization schemes could be used.
Also, "the heap" is an over-simplification, because a HotSpot JVM / GC typically divides the heap into areas with different characteristics. For instance the "permgen" area of the heap (where static frames and code blocks are allocated) is only garbage collected rarely.

To complement previous answer:
The functions are stored in special area, but a reference to them is stored in the object (for non static functions).
Reference to static functions is stored in another area (you can think they are stored just next to static fields) (static memory area).
All objects are stored in heap (Object Pool), but the place of reference to them vary, local variables are in the stack, non static fields are stored in the object itself, so they are stored in the heap too.
Static references are placed in another special part of the memory, (although if they are references to Objects, they point to heap).

Related

When is memory allocated during instance creating or using new keyword for object creation?

As I read somewhere, memory is allocated when instances are created and a space is allocated from the heap. If it is right than when and how much exactly memory is allocated during instances and objects creation?
Variables declared within a method are stored within the stack, while the actual objects are stored on the heap. Consider
Integer a = new Integer(10);
In this example, an object of type Integer is created on the heap and a reference (either 32 or 64bits) is returned and stored within the methods stack as variable 'a'. The JVM is free to keep variables like this within the CPU registers if it prefers as an optimization.
Memory of an object is allocated when the new keyword is used. It is usually assigned within the TLAB (thread local allocation buffer) which is part of the eden heap reserved to the running thread. Thus reducing the overheads of object allocation to a simple 'bump of a pointer'. The two times when the TLAB is not used, is 1) when the object is too large for the space remaining, inwhich case it will be promoted straight to the old gen and 2) when a supporting JVM decides via escape analysis that it can avoid the object entirely and allocate directly on to the stack (or even break the object apart and only assign the fields required on the stack).
The amount of memory reserved consists of an object header, usually 2 words (3 for an array) and then space for each of the fields declared in the object and its parent classes. The total size of those fields depends on the JVM and the underlying platform (eg 32 bit or 64 bit) and JVM configuration such as compressed references.
------------------+------------------+------------------ +--------------------------
| mark word | klass pointer | array size (opt) | padding and fields |
------------------+------------------+-------------------+--------------------------
Asking the JVM for sizes is not officially supported, but EHCache sizeOf is a very good 'best guess' that uses knowledge of different JVMs and access to the underlying pointers via the use of Java Unsafe.
The starting place for understanding the size of each field is the size of primitives defined by the Java language, however this is only the minimum sizes as the JVM is designed to work with 32bits and so primitives smaller than this are often padded out to 32 bits. For example booleans.
The exact layout of the fields will vary by JVM, but they will tend to be grouped by the class that defines them starting from the root of the inheritence tree. For example, consider
and
The pictures above were taken from this very good blog post that describes the memory layout very well,
"create instance" has the same meaning as "use new to create new object".
In a normal case, heap memory will be allocated at the time you ask for a new object, but that is not set in stone: HotSpot can also determine that it is safe to allocate the object on the call stack (by the process of Escape Analysis). This is more efficient as it doesn't need any garbage collection.
How much memory is allocated is highly implementation-specific, only Java arrays are guaranteed to be "packed" (modulo a fixed overhead). Boolean arrays, though, are specified as occupying a byte per element.
I'm reading your question as: "Who actually allocates memory for an object - the new keyword or the constructor?" If that's the case, the answer is the new keyword.
Constructors are typically chained, meaning that at least two constructors will run when you're creating an instance. On the other hand, memory for an instance is allocated only once.
Also, the type of allocation is determined using analysis of the usage of the produced reference (escape analysis, for example). This means that the most obvious place for the allocation to happen is at the constructor call site (that is, the place of the new expression).
The size of the memory allocated is such that it can accomodate an instance of the type following the new keyword. That latter size (the size of an instance of a type) is
the aggregate size of the primitive types (int, float, double, etc) it consists of,
plus the aggregate size of the references to the reference types (class or interface instances) it consists of,
plus "secret" stuff embedded in instances so that Java features can work (like a virtual table pointer, to allow fast runtime resolution of virtual method calls)
plus possible padding between each of those (to align the various types to their optimal address number multiples in memory).
In any case, when you do T obj1 = new T(), where T is the name of a class:
Memory is allocated somewhere to accomodate a T instance.
The instance is constructed.
If the instance is successfully constructed, a reference to the instance is returned.
That reference is stored in the obj1 variable.
When you do R obj2 = new R(), a similar thing happens for the type R, and type R may have a different size than T.
But neither of these local variables contains the instance. They both contain a reference to their assigned object. (Thus, the variables themselves might even be of the same size, if all they have to do is store a memory address.)
As I read somewhere that memory is allocated when instances are created and a space is allocated from the heap.
yes you are right, until and unless new is called it's just a null reference that is pointing to nothing.
If it is right than when and how much exactly memory is allocated when instances and objects are created?
It depends on the size of the object.
Have a look at Primitive Data Types to know about their size.
In Java, what is the best way to determine the size of an object?
Read more...
Class Variables
When a number of objects are created from the same class blueprint, they each have their own distinct copies of instance variables. In the case of the Bicycle class, the instance variables are cadence, gear, and speed. Each Bicycle object has its own values for these variables, stored in different memory locations.
Sometimes, you want to have variables that are common to all objects. This is accomplished with the static modifier. Fields that have the static modifier in their declaration are called static fields or class variables. They are associated with the class, rather than with any object. Every instance of the class shares a class variable, which is in one fixed location in memory. Any object can change the value of a class variable, but class variables can also be manipulated without creating an instance of the class.
https://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html

In Java, is a global variable always put on the heap?

Also, how does having a static variable affect things? (If at all) For example:
class MyClass{
static int[][] data;
static {
data = new int[some number][some number]; /*read data into array*/
}
static void run() {
/*now use data here*/
}
}
Is this put on the heap? Comparing that example with
class MyClass{
static void run() {
int[][] data = new int[some number][some number];
/*now use data here*/
}
}
How much difference is there between these two code examples? Please shed any insight.
Java has a concept of PermGen space - this is the space used to store all class definitions, static variables, interned strings, etc.
here is link
This Java heap memory is structured again into regions, called generations. The longer an object lives, the higher the chance it will be promoted to an older generation. Young generations(such as Eden on Sun JVM) are more garbage collected than older generations(survivor and tenured on Sun JVM). However, there is also some separate heap space called permanent generation. Since it is a separate region, it is not considered part of the Java Heap space. Objects in this space are relatively permanent. Class definitions are stored here, as are static instances.
A full description of PermGen space can also be found here, although note that this is changing with Java 8: here is link
Static variables are stored there, dynamically allocated things are stored in the regular heap.
(Note that even for the static array the things placed within the array are dynamically generated).
Your second example is better for this case though unless you really need to remember the contents of that array between calls. You are using up memory all the time to store an array that you only need while you are inside the method. Additionally by having the static data like that your method is not re-entrant. That means that if two threads call the method at the same time then they will interfere with each other and give bad results.
Every object, that you create while your program is running, is created in the heap space. I think this is the most important thing to understand, when you are asking for antyhing "better".
A variable can be a local variable inside a method (method parameters are also local in this sense), or they belong to an instance or to a class. Here is the difference. The memory for local variables is allocated on the thread's stack, the memory for instance and class variables reside in the corresponding object's space, which is in the heap.
Keep in mind, that variables only store references to objects. They do not store the object! Therefore the memory consumption of variables is very low.
There are just two places where data can reside in JVM: the heap and the stack (well, JNI tricks inclusive it can reside anywhere, but this is an exception). All local variables in methods are located on the stack, everything else - on the heap. In both your examples array data is allocated on the heap, though in the second example the reference maze is a method local variable so is itself located on the stack.
One thing you must carefully distinguish is the following:
placement of the reference-typed variable;
placement of the referent (the array in your case).
If I follow your thoughts correctly, you are not really interested in 1., which is just four bytes, but in 2.
If the variable which refers to the array is static, the array will be placed on the heap;
if the variable is local, and if the JIT compiler can prove that your array will definitely not be reachable when your solve method completes, then there is a chance that the whole array will be stack-allocated.
For arrays, which are quite large, but efficiently allocated objects, it will make very little difference where they are allocated—as long as they don't get tenured into the Old Generation. If they do get tenured regularly, then you will probably experience significant slowdowns due to frequent Full GC cycles.

Java variable placed on stack or heap

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.

Where does class, object, reference variable get stored in Java. In heap or in stack? Where is heap or stack located?

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.

Since all objects are created with "new" in Java, does this mean they are all created on the Heap?

The purpose of this query is to compare one aspect of Java and C++, that has to do with the "new" operator.
Now, I know that in C++ there are two ways to create objects; with or without the "new" operator. In the absence of that operator, space is not allocated in the heap region, whereas, in its presence, space is allocated in the heap region.
What about Java? I notice that the "new" operator is used for creating every object. Even arrays are created with the "new" operator. Does it mean that in Java there is only one place for objects to exist in - that is, the heap region?
Thanks.
Yes, the new operator always allocates memory for the object on the heap. Unlike C++, objects in Java cannot be created on the stack.
Local primitive types, and local references to object types, both take up "stack" memory, as do they both when passed as parameters to methods.
All objects themselves exist in the equivalent of a "heap".
All Java objects (i.e. all things with a reference) are allocated in the heap1 from the perspective of the application and the application programmer2. Java does not support explicit allocation of objects on the stack. Object references can be stored both in heap nodes (i.e. class or instance fields) and stack frames (i.e. local variables, etc).
In fact, there are a few ways that first class Java objects can be created in Java that don't involve using the new keyword.
The { ... } array initializer syntax can be used in an array declaration without the new keyword.
A String literal involves the creation of a String object (at class load time).
The boxing conversion will (typically) create a new wrapper object without an explicit new or method call.
The reflective newInstance and similar methods create objects without an explicit new.
Under the hood, the implementation of Java serialization uses a special method in the Unsafe class to create objects without executing any declared constructor.
You can also create Java objects in native code using the JNI / JNA apis.
(There is a strong argument that the last two are "not Java", but they are worth mentioning anyway. And the String literal and auto-boxing cases involve Java code that uses new under the hood.)
1 - There can be more than one heap, though this is transparent to the application.
2 - The latest Hotspot JVMs have an experimental "escape analysis" feature that determines whether objects "escape" from the context in which they are created. Objects that don't escape could be safely allocated on the stack. Once again, this optimization is transparent to the application.
In Java, all objects are dynamically allocated on Heap. This is different from C++ where objects can be allocated memory either on Stack or on Heap. In C++, when we allocate abject using new(), the abject is allocated on Heap, otherwise on Stack if not global or static.
In Java, when we only declare a variable of a class type, only a reference is created (memory is not allocated for the object). To allocate memory to an object, we must use new(). So the object is always allocated memory on heap.
Example 1: Give Compile Error.
class Test {
void show() {
System.out.println("Test::show() called");
}
}
public class Main {
public static void main(String[] args) {
Test t;
t.show(); // Error here because t is not initialed
}
Example 2: Allocating memory using new() makes above program work.
class Test {
void show() {
System.out.println("Test::show() called");
}
}
public class Main {
public static void main(String[] args) {
Test t = new Test(); //all objects are dynamically allocated
t.show(); // No error
}
}

Categories

Resources