let have an example.
public class test {
public static void main(String args[]) {
int a=5,b=4;
int c=a+b;
int d=9;
System.out.println("ANSWER PLEASE..");
}
}
Now when we execute this code what os does?
It first create a variable named a and alocates a memory address similar things for b and c.
now what happen to d. os creates a new memory address or it just reffer to the address of c as the value is same.
First of all, the compiler doesn't do much. It basically translates it into class-files / bytecode. In the bytecode there is a number called "max locals" which tells how many local variables are required to run the method.
The JVM on the other hand, which reads this information and runs the code makes sure memory is allocated on the stack frame to fit the required variables. How much it asks for is highly implementation dependent, and it may very well optimize the whole thing, and allocate fewer bytes than what's indicated by the code.
what happen to d. os creates a new memory address or it just reffer to the address of c as the value is same.
This is tagged Java. So let's keep the OS out of it. Everything happens in memory managed by the JVM, which is allocated in big chunks in advance.
You are talking about primitive data types. Those are easy, as they are stored by value, not as references to objects living elsewhere.
You are talking about local variables. Those are allocated on the running thread's call stack (not in heap memory). Since they are primitive here, too, this does not involve the heap at all.
In your case, there is memory allocated (on the stack), for the four integers. Each of them contains the value assigned to it, not a reference. Even if the same value is assigned to all of them, they exist separately. The memory is "freed" (not really freed, but no longer used by the thread) when the method returns.
If those were not integers, but Objects, you could "share pointers" (to objects on the heap), but integers are stored by value (four bytes each).
Related
I am wondering when is Java creating variables during runtime (when a function is called). Please see the examples below and answer whether those are one the same.
void function someFunction(boolean test) {
if (!test) {
return;
}
int[] myVar = new int[1000000];
...
}
void function someFunction(boolean test) {
int[] myVar = new int[1000000];
if (!test) {
return;
}
...
}
I wouldn't like so spend time allocating memory only for it to be deallocated moments later, so I need to know whether Java will allocate memory needed for a certain variable (or array) needed by a function at the very beginning of that function, regardless of where the declaration happened, or will it allocate memory when it reaches the point of declaration.
EDIT:
I'm terribly sorry for confusion I'm causing. When I say variable I mean object.
Probably at the point of method entry. It is a common compiler optimization to allocate a stack frame large enough to contain all locals. If that's so, it's pretty much a single subtraction to allocate space for them all. But you'd have to examine the bytecode to be sure.
However, in this:
int[] myVar = new int[1000000];
the 'variable' is a single reference, taking up 4 or 8 bytes. The object to which the variable refers is allocated at the point the initialization is encountered in execution, by the execution of the 'new' operator.
I suspect you need to read up on the distinction between variables and objects.
In general, the Java compiler is a bit dumb in its compilation since it leaves the optimization up to the runtime JVM. As such, the compilation is mostly a straightforward translation of source code into bytecode.
https://godbolt.org/z/5xT3KchrW
In this case with the OpenJDK 17.0.0 compiler, the allocation of the array is done roughly at the same point in the bytecode as where the source code indicates.
However, the local variable of the pointer to the array is "allocated" at the time the method is called via registers. While the JVM uses a stack frame in a way very similar to C/C++, on Android's Dalvik they instead use registers to hold local variables so it isn't ever actually "allocated" at all in memory (a design decision due to the focus on ARM -- with it's plentiful registers -- rather than x86 -- which is infamous for its lack of registers.
I'm considering about how Java and C manage variable in a scope.
In java, every iterator, I create a new object and then print it. The result say that each iterator I have a new Object.
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
while (true) {
Ideone object = new Ideone();
System.out.println(object);
}
}
}
And variable of scope in C. I do the same as I do in Java. Every iterator I create a variable and print its address. But the result make me confusing because it's returning the same address, because I think every iterator it create a new variable at a random address
#include <stdio.h>
int main() {
while (1) {
int variable;
printf("%p\n", &variable);
}
}
Can anyone tell me what's under the hood of Java and C ?? And why C do not create a random address for it's variable ?
EDIT 1:
I have another question about dynamic memory management in C like this:
#include <stdio.h>
int main() {
while (1) {
int *variable = malloc(sizeof(int));
printf("%p\n", variable);
}
}
In this case, they print different address after each iterator. And each address is more then the previous the constant size.
But if free the memory like this, now it print the same address
#include <stdio.h>
int main() {
while (1) {
int *variable = malloc(sizeof(int));
printf("%p\n", variable);
realloc(variable, 0);
}
}
Is C memory management do not generate random address for new variable ?
In Java, the new Ideone() objects lifetime is not bound to a scope, you could return it from a function.
In your C code, int variable; creates an object that is automatically destroyed when you reach the end of the scope it was defined in.
Many implementations of C use a stack to allocate such objects. A stack will always give you the same address when used this way.
This comparision is a bit like apple vs. oranges. Comparing Java's new to C's malloc would show a similar behavior.
You're comparing apples to kumquats here - you're printing out the value of object (which is the address of something explicitly created on the heap each time through the loop) vs. the address of variable (which is an auto object that's typically allocated from the runtime stack).
variable has auto storage duration, meaning that storage for it is only guaranteed to be allocated over the lifetime of its enclosing scope (i.e., the body of the loop). However, as a matter of practice, most C compilers will allocate space for all auto variables in a function at function entry, even if the scope of those variables is limited to a smaller block within the function. IOW, the space for variable is allocated once, so its address doesn't change from iteration to iteration. And, given how most C implementations manage auto objects, it would be allocated from the same address anyway if it were allocated and deallocated with each loop iteration.
A more direct comparison would be looking at the address of the object variable itself, not its value, but I'm not sure how you would obtain that information (been a long time since I've done any Java).
In your Java code, you explicitly create a new object with every run in the loop. Thus, it is very likely that the different objects yield different memory addresses.
In you C-code, in contrast, you do not "create" anything, because variables are actually not "created". They are concepts of the programming language, and the compiler may decide when, where, and how often it reserves memory for the variable to hold a value. In practice, local variables are placed on the stack once at the beginning of a function or a loop, so it seems as if it were "created" only once, but this is actually something you cannot rely on.
Note, however, that the situation becomes a different one if you allocate "objects" in C as well. This would be rather comparable then to what Java does (in Java, all class-based types are handled through a pointer, but this isn't exposed to the user):
#include <stdio.h>
int main() {
while (1) {
int *variable = malloc(sizeof(int));
printf("%p\n", variable);
}
}
Besides memory leaks and running out of memory, this will print different memory addresses with each iteration.
Java use virtuel machine JVM. The garbage collection delete the variables when it's not needed any more.
In C the variables are stored in the stack or heap which you need you use malloc to allocate memory and free to deallocate.
Your output shows the address of variable in hexadecimal where in memory it's located and it's compilers decision in which memory address it should be stored.
local variables are put on the stack since in your code you did not used malloc to allocate memory on the heapit will give you the same address because stack is Last-in-first-out and your loop PUSH and POP in the same address, but if you close your terminal and run it again it will give you different address.
Close terminal and reopen run again it gives different address.
I know JVM uses stack and heap for allocation of memory for object reference, object value and memory for methods. But I am confused about the terminologies: METHOD AREA, HEAP and JAVA STACK and I have few question's.
When we say "ClassName obj = new ClassName()", new creates an object on the HEAP(the instance variables and static variables too) and what is returned to the reference(obj)? Some people use to say it is CLASS TYPE, does it mean the hash code?
When new creates the object on the heap, at the same time: i)the methods,corresponding to that object ii)local variables and iii)the reference to that object are stored as part of STACK( is it JAVA STACK?). If so, then what does METHOD AREA do? Or am I wrong?
What is the amount of memory allocated for that object?
i. for object reference
ii. for object values(it depends on the local variables)
iii. will there be a memory allocated to point the object's methods?( because the non-static members are not shared among the objects and a separate copy is maintained for each objects including the methods).
By the way, where does static methods are stored?
When we say "ClassName obj = new ClassName()", new creates an object
on the HEAP(the instance variables and static variables too) and what
is returned to the reference(obj)? Some people use to say it is CLASS
TYPE, does it mean the hash code?
Yes new creates Object on the HEAP. Heap is a memory place where the objects and its instance variable are stored. Not static variables since static variables doesn't belong to Object it belongs to class so are stored on PermGem Sections (class related data, not instance related).
What is Returned : the reference(pointer/memory address) i.e hashcode
When new creates the object on the heap, at the same time: i)the
methods,corresponding to that object ii)local variables and iii)the
reference to that object are stored as part of STACK( is it JAVA
STACK?). If so, then what does METHOD AREA do? Or am I wrong?
since All threads share the same method area methods don't corresponds to Objects it belongs to class
what does METHOD AREA do :The method area stores per-class information, like Run Time Constant Pool, Method code, The method's return type (or void) etc
What is the amount of memory allocated for that object? i. for object
reference ii. for object values(it depends on the local variables)
iii. will there be a memory allocated to point the object's methods?(
because the non-static members are not shared among the objects and a
separate copy is maintained for each objects including the methods).
Amount of Memory for Object Reference: it depends as on many VMs the size of a reference is the native pointer size and for (iii) above point already cleared that
I know JVM uses stack and heap for allocation of memory for object reference
correct.
object value
I assume you means the object's header and fields.
and memory for methods.
Methods are not stored in the heap, or stack. When you profiler the heap usage or set the maximum heap size, the use of methods makes no difference as they are not on the heap in the Oracle or OpenJDK JVM.
They are stored in the PermGen or MetaSpace or some other space depending on which JVM you are using.
But I am confused about the terminologies: METHOD AREA,
From Method Area in Java
The Java Virtual Machine has a method area that is shared among all Java Virtual Machine threads. The method area is analogous to the storage area for compiled code of a conventional language or analogous to the "text" segment in an operating system process. It 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 (ยง2.9) used in class and instance initialization and interface initialization.
HEAP
Shared space for storing objects. This is usually one continuous region of native memory managed by the JVM.
and JAVA STACK
The thread's stack which is actually a native thread stack on most JVM.
When we say "ClassName obj = new ClassName()", new creates an object on the HEAP(the instance variables and static variables too)
It might, but it can also eliminate the object with escape analysis, placing the fields on the stack, and possibly eliminating those.
and what is returned to the reference(obj)?
Correct, Java only has references and primitives (if you ignore the void type which is neither)
Some people use to say it is CLASS TYPE,
The reference is defined by giving the type of the reference which is a class or interface.
does it mean the hash code?
A hash code is a hash value for the object. It is not releated to anything else you have mentioned.
When new creates the object on the heap,
When you create a new object on the heap, you just create space for the header of the object (which points to the class and it's methods) and space for it's fields. (Those the JVM doesn't optimise away)
at the same time: i)the methods
The methods are loaded/compiled in various stages. The methods are loaded as they are needed for the first time and later if they are compiled.
corresponding to that object ii)local variables
Local variables are on the stack, not on the heap, not in the object.
iii)the reference to that object are stored as part of STACK( is it JAVA STACK?).
The Java Stack, is the Stack, is the native stack.
If so, then what does METHOD AREA do?
Store the code for the methods.
What is the amount of memory allocated for that object?
About 8-12 bytes per header, space for each primitive field and reference and alignment padding of 8 or 16 bytes (32 GB - 64 GB heaps).
i. for object reference
Typically this is 32-bit on 64-bit JVMs (With compressed oops). If you have more than 64 GB heap it will be 64 -bit.
ii. for object values(it depends on the local variables)
Local variables are on the heap not the object.
iii. will there be a memory allocated to point the object's methods?
Method memory usage is not visible to you. It is not on the heap, nor something you can measure on a per method basis. I don't know of a profiler which will even show you this.
( because the non-static members are not shared among the objects and a separate copy is maintained for each objects including the methods).
That sounds like an insane waste of space, and it is, which is why the JVM does do that. There is only one copy for a method, regardless of the number of instances.
By the way, where does static methods are stored?
With all the other methods. There is no difference between a static method and a non-static method except a non-static method must take an instance as it's first argument at the JVM level. (And there is a bit in the modifiers to say whether it is static or not)
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.
In Java we have written a code:
A a1;
a1 = new A();
How many bytes of memory is reserved when compiler compiles the code:
A a1;
That's not specified by the Java standard and thus you should not worry about it.
Technically, references are usually as big as the machine's word size, i.e. 32 bit on a 32 bit machine and 64 bit on a 64 bit machine, though some 64 bit JVMs use special magic to allow 32 bit references.
One pointer's worth of memory is used on the stack. That should be 32 bits (4 bytes) unless your machine's in 64-bits mode.
edit:
I see that some people are confused and think that the A object itself is allocated on the stack. That is not the case in Java: all objects are allocated on the heap (modulo JIT optimizations of course). The line A a1; simply allocates pointer a1, initially set to NULL. The pointer itself is in the stack, though of course what it points to will be on the heap. The later call to new A() will allocate an A object on the heap, and the size of that allocation does depend on what's in A.
That depends on the platform and the implementation. For a 32-bit platform, a 4 byte pointer is used behind the scenes on object instances, regardless of the size of class A.
Edit:
The Java compiler does not reserve any memory for this, that's the runtime's (to be exact, the JIT's) responsibility.
A variable reference is a handle to an object on the heap, so it will take up a fixed amount (depending on the JVM implementation). However, just for that line, the compiler may not take up anything, since the variable has not been initialized yet. This is statically checked by the compiler, so it will know when it needs to allocate the variable and may in fact allocate it only when it is first assigned.
If you had a method:
public static void method() {
A a1;
}
I would expect the compiler to optimize it out completely, as it can't do anything with it.
All that being said, in Java programming, you just don't worry about these things, they are determined by the JVM implementation and Java is not suitable for byte-level memory concerns. If you are counting bytes like that, you should be using C or some similarly close-to-the-metal language.
Was your question: How much space does a reference occupy in Java?
If that's the case I'm not sure, sorry.
A a1;
All the above does is define a local variable on the execution stack so no heap memory is reserved.
Enough to store a reference to any A! :-)
Note that it's generally impossible to know exactly how many bytes a particular implementation will actually use for a particular allocation, even in low-level languages like C: malloc() itself is a function which obviously needs to maintain internal data structures. To avoid fragmentation, it usually allocates a 2^n-sized block of memory. And so on.
If you're concerned about how much memory is actually used, write a sample program, and run it through your profiler.
As has been mentioned, it will use either 32-bits or 64-bits, however if the reference is only placed in a register, it might not use any memory.
reference variable occupies bytes which are solely dependent on arhitecture of jvm (8 bytes for 64 bits and 4 for 32 bi
A a1; allocates on the stack, not the heap.
However, this is all up to implementation, and is not actually defined, as far as I know.
Even for the amount of memory in the stack, that will depend of what is contained/defined in A.
null does not occupy any space in memory.
Simply saying int occupies some bytes like float occupies some space in memory.
But for null no space is occupied in memory.
Send me details if my answer is wrong.
Try for system.memorrysize() like method in Java.