In C++ we used sizeof() operator, which function can we use in Java to check the size of an object?
My basic doubt is that whether the reference variable in java has any size or not. Consider the following example:
SampleClass obj = new SampleClass();
Here, will obj have any size? If yes, How can we check it in Java?
obj is a variable, not an object. The value of obj is a reference - which is likely to be 4 or 8 bytes, depending on the JVM.
The size of the object that the value refers to is also JVM-dependent. As several objects can refer to each other, it's generally tricky to talk about the size of an object in Java in any particularly useful way... what usually matters is how much more memory would be potentially available if a particular object became eligible for garbage collection, and that depends on what other objects the first object refers to - and whether there are other objects that refer to those, too.
Obviously the "raw" size of an object is somewhat important too, and at least somewhat easier to predict (to an approximation, at least), but it's still VM-specific and can't easily be requested at execution time. (You could create millions of objects, prevent them from being garbage collected, and measure memory differences, but that's the closest I know of, at least outside a debugger API.)
Since you found my comment superb, I just had to post it as an answer, although it may be superflous to the already existing answers:
Rest assured that a reference variable (like obj) has a size, although there won't be a platform-independent answer on how large this size is, but there definitely should be a size. But due to this platform (or JVM) dependence, Java is not the language to mess with such low-level details.
Maybe the compiler can optimize some reference variables away as being just aliases for others, but in general obj has to have a size, as it has to somehow store the reference (whatever this is, it is something and not nothing).
obj is only the reference to an instance of SampleClass.
The size that the instance of SampleClass occupies in the memory depends on the elements the files of the object, and VM. But even a reference need some memory of course (like in c)
But the java memory model is much more complicated. If you are really interessted in how much memory the object need, then I strongly recommend to use a memory analyzer.
Anyway: because java is a VM and the Java VM has the garbage collector, there is no real 1:1 relation ship between the size of the memory you would expect by counting the (living) java objects and the memory the VM allocates from the Operation System.
You might try getting some insight on the "size" of the reference by using the freeMemory method of the Runtime class.
For example, allocate an array of 1000000 null references:
SampleClass[] array = new SampleClass[1000000];
Check the free memory before and after; the difference may give a hint on what you want to know (the array itself is an object, though its size is probably much less than 1000000, so the measurement must be pretty precise).
Related
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
Here's my understanding.
In C programming, if I do int a then that a is created on stack and thus the memory is taken from stack. Heap plays no part here.
But if I do something like
int *a;
a=(int*)malloc(sizeof(int));
and dynamically allocate the memory, then the reference variable will be placed on stack, but the memory it points to will be on the heap.
Am I correct with my understanding?
Now, I picked up this book on java that says
Whenever you need an object, you
simply write the code to create it by using new, and the storage is allocated on the
heap when that code is executed.
So there's no way of creating objects on Stack in Java?
I guess, the primitive data types can still be placed on stack, but I am concerned about the Objects.
There is no way to create objects on the stack in Java. Java also has automatic garbage collection, so you don't have any way of deleting objects. You just let all references to them go out of scope and eventually the garbage collector deals with them.
That is correct. Objects are stored on the heap. The stack contains primitive values like int and double (from local variables) and references to objects (again from local variables).
The whole premise of your question is false: in Java you don't have any control over where the objects will be allocated. Some are indeed stack-allocated, but you'll never notice the difference.
What is fundamentally different between Java and C is that in Java the value of a variable can never be the object itself, whereas in C the value can be the struct itself, with no indirection. You can pass such structs by value to other functions and there is no equivalent of that in Java.
In java, When we call a new Constructor(), then a new object is created each time i.e; a new memory is allocated or suppose there are already many objects created for a class that do not have any reference.
So can java return such object that are marked for de-allocation or will the java create a new object each time a new constructor() is called.
What's my basic intention to ask this question is if such thing happens then performance can be improved as the cost to create a new memory and destroying a un-refrenced object will be reduced.
Yes.
Java will never re-use an object.
Java always creates new object. Note that new operator is very fast in Java. There is no allocation, typical JVM will just increment one pointer on heap. Once heap is full, old and unnecessary objects are removed and live are compacted. But garbage collection is a different story.
Your idea is clever, but would actually worsen performance. JVM would not only have to keep track of dead objects (eligible for GC) which it is not doing. But also it would have to clean up the old object somehow, so that it appears to be fresh. That's non-trivial and would take a lot of time. new is both faster and simpler.
There is one catch, though:
Integer answer = 42;
42 is a literal that has to be converted to Integer object. However JVM won't simply call new Integer(42) but Integer.valueOf(42) instead. And in the latter case valueOf() sometimes returns cached values (it will e.g. for 42).
Yes, when you use new in Java, a new object is always created.
However, that does not necessarily mean that the JVM has to ask the operating system to allocate memory. How the JVM exactly allocates memory is up to the particular JVM implementation, and most likely it contains a lot of optimizations to make it fast and efficient.
Object allocation is generally considered a cheap operation in Java - usually you do not need to worry about it.
One example of a sophisticated optimization that's implemented in the current versions of Oracle's Java is escape analysis.
The cost of creating objects and destroying unreferenced object is trivial. What takes the time is
detecting when an object is no longer referenced. To do this every strong reference must be checked.
copying objects which are kept from one generation to another and defragmenting a generation.
finalising objects which implement the finalize() method.
If you create short lived temporary objects whether your Eden size is 8 MB or 8 GB, the time it takes to do a minor collection is almost the same.
There is a design pattern called flyweight, its main advantage is to reuse objects. Java uses that in creating strings itself.
you can learn more about it here: http://en.wikipedia.org/wiki/Flyweight_pattern
Wherever you see new(), you can be pretty sure that a new object is being created.. As simple as that..
I have been lately reading a lot on memory allocation schemes in java, and there have been many doubts as I have been reading from various sources. I have collected my concepts, and I would request to go through all of the points and comment on them. I came to know that memory allocation is JVM specific, so I must say beforehand, that my question is Sun specific.
Classes (loaded by the classloaders) go in a special area on heap : Permanent Generation
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.
All the static member variables are kept on the Permanent Generation area again.
Objects go on a different heap : Young generation
There is only one copy of each method per class, be the method static or non-static. That copy is put in the Permanent Generation area.
For non-static methods, all the parameters and local variables go onto the stack - and whenever there is a concrete invocation of that method, we get a new stack-frame associated with it.
I am not sure where are the local variables of a static method are stored. Are they on the heap of Permanent Generation ? Or just their reference is stored in the Permanent Generation area, and the actual copy is somewhere else (Where ?)
I am also unsure where does the return type of a method get stored.
If the objects (in the young generation) needs to use a static member (in the permanent generation), they are given a reference to the static member && they are given enough memory space to store the return type of the method,etc.
Thank you for going through this !
First, as should be clear to you by now that there are very few people who can confirm these answers from first hand knowledge. Very few people have worked on recent HotSpot JVMs or studied them to the depth needed to really know. Most people here (myself included) are answering based on things they have seen written elsewhere, or what they have inferred. Usually what is written here, or in various articles and web pages, is based on other sources which may or may not be definitive. Often it is simplified, inaccurate or just plain wrong.
If you want definitive confirmation of your answers, you really need to download the OpenJDK sourcecode ... and do your own research by reading and understanding the source code. Asking questions on SO, or trawling through random web articles is not a sound academic research technique.
Having said that ...
... my question is Sun specific.
At the time this question was asked, Sun Microsystems had ceased to exist. The question was therefore Oracle specific. AFAIK, all current (non-research) 3rd-party JVM implementations are either direct ports of an OpenJDK release or descended from another Sun/Oracle release.
The answers below apply to Oracle Hotspot and OpenJDK releases, and probably to most others as well ... including GraalVM.
1) Classes (loaded by the classloaders) go in a special area on heap : Permanent Generation.
Prior to Java 8, yes.
As of Java 8, the PermGen space has been replaced with Metaspace. Loaded and JIT-compiled classes now go there. PermGen no longer exists.
2) 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.
More or less, yes. I'm not sure what you mean by some of those things. I'm guessing that "internal objects used by JVM (like java/lang/Object)" means JVM-internal class descriptors.
3) All the static member variables are kept on the Permanent Generation area again.
The variables themselves yes. These variables (like all Java variables) will hold either primitive values or object references. However, while the static member variables are in a frame that is allocated in the permgen heap, the objects/arrays referred to by those variables may be allocated in any heap.
4) Objects go on a different heap : Young generation
Not necessarily. Large objects may be allocated directly into the tenured generation.
5) There is only one copy of each method per class, be the method static or non-static. That copy is put in the Permanent Generation area.
Assuming that you are referring to the code of the method, then AFAIK yes. It may be a little more complicated though. For instance that code may exist in bytecode and/or native code forms at different times during the JVM's life.
... For non-static methods, all the parameters and local variables go onto the stack - and whenever there is a concrete invocation of that method, we get a new stack-frame associated with it.
Yes.
... I am not sure where are the local variables of a static method are stored. Are they on the heap of Permanent Generation ? Or just their reference is stored in the Permanent Generation area, and the actual copy is somewhere else (Where ?)
No. They are stored on the stack, just like local variables in non-static methods.
6) I am also unsure where does the return type of a method get stored.
If you mean the value returned by a (non-void) method call, then it is either returned on the stack or in a machine register. If it is returned on the stack, this takes 1 or two words, depending on the return type.
7) If the objects (in the young generation) nees to use a static member (in the permanent generation), they are given a reference to the static member && they are given enough memory space to store the return type of the method,etc.
That is inaccurate (or at least, you are not expressing yourself clearly).
If some method accesses a static member variable, what it gets is either a primitive value or an object reference. This may be assigned to an (existing) local variable or parameter, assigned to an (existing) static or non-static member, assigned to an (existing) element of a previously allocated array, or simply used and discarded.
In no case does new storage need to be allocated to hold either a reference or a primitive value.
Typically, one word of memory is all that is needed to store an object or array reference, and a primitive value typically occupies one or two words, depending on the hardware architecture.
In no case does space need to be allocated by the caller to hold some object / array returned by a method. In Java, objects and arrays are always returned using pass-by-value semantics ... but that value that is is returned is an object or array reference.
For more information, please refer to these resources:
Class metadata: a user guide
What is the difference between PermGen and Metaspace?
Java 8: From PermGen to Metaspace
About G1 Garbage Collector, Permanent Generation and Metaspace
How much space does an object takes from the memory heap? How can this be done?
This is far more complex than just using free memory computations (which don't take into consideration garbage collections and new allocations by other threads). Take a look at:
http://www.javaspecialists.eu/archive/Issue142.html
This is advanced stuff, however.
--EDIT--
The solution above finds the deep size of an object (using a stack to traverse the reference network, a collection of visited references, and of course instrumentation).
However, getting the shallow size of an object is simpler, and can be achieved by java 1.5 instrumentation without extra work (see Instrumentation.getObjectSize()).
The amount of memory taken by an object varies from one JVM implementation to the next and sometimes from one platform to the next.
You can estimate the amount by counting up the number and size of primitive types and object references declared as instance variables of the object's class.
For example:
public class Monkey {
int arms;
Animal parent;
}
..has 1 object reference and 1 int primitive, which on a 32-bit architecture will take up approximately 8 bytes per instance.