This question already has answers here:
What is null in Java?
(14 answers)
Closed 9 years ago.
If I declare some string variable like
String str = null;
Is there memory allocated for variable str?
If allocated, how many bytes will be allocated?
If not allocated, how does the JVM know that there is some variable called str been declared?
If allocated and if there is null value inside the memory, then what exactly is the representation of null in binary?
When you do something like:
String str = null;
The only thing allocated is a reference to a string (this is analogous to a string-pointer in languages which contain pointer-types). This reference is a 32 or 64 bit variable (depending upon your hardware architecture and Java version) which resides on the stack (probably, depending upon the exact context in which your declaration is placed).
No memory should be allocated for the null itself, because null is not actually a valid object instance. It is simply a placeholder that indicates that the object reference is not currently referring to an object. Probably it is simply the literal value 0, such that assigning an object reference to null is equivalent to setting a pointer type to NULL in C/C++. But that last bit is conjecture on my part.
Null is the value of a reference that is not bound to an object.
Space is allocated for the reference variable itself, regardless of its value. Null is merely a value that fits within this space.
To answer each question for the specific example.
Yes, there is space allocated for the variable str.
The size of the memory allocated for the reference variable is probably four bytes.
It is allocated, and the JVM follows the instructions of the compiled code to access it.
It doesn't matter.
Take a look at this Java IAQ (infrequently asked question) "Is null an object?".
To answer your questions:
Only memory to store the reference is allocated
The java standard doesn't specify how much memory a reference takes up (although, in practice it is usually 32 or 64 bits depending on your JVM - although some JVMs try to beat this)
The memory representation of null doesn't matter, since you can't do bit level operations on it (or assign it to anything that isn't a reference)
Java works on references. Think of String str=null as you have pointer in C, but not exactly pointer.
Now internal representation dependes upon the JVM. It is not easy to calculate the size of reference. The implementation differs per JVM so there is no point extracting that low level info.
After doing this line:
String str = null; // or String str;
Only a reference of type String is allocated into the stack. null means that you don't assign any value (object) to the reference str into the heap.
Related
I'm curious to know how Integer and Integer Array are stored on the stack/heap in java, is there a link someone could point me to? Or could someone explain it to me please.
Update 1:
and how does this affect the way an integer and an integer array are passed as arguments to methods in Java.
Thank You
Whenever you declare a variable within a local scope(a method) it gets put on the stack.
That is: Type myVariable will push space for a new variable onto that methods stack frame, but it's not usable yet as it's uninitialized.
When you assign a value to the variable, that value is put into the reserved space on the stack.
Now here's the tricky part. If the type is primitive, the value contains the value you assigned. For example, int a = 55 will literally put the value 55 into that space.
However, if the type is non primitive, that is some subclass of Object, then the value put onto the stack is actually a memory address. This memory address points to a place on the heap, which is where the actual Object is stored.
The object is put into the heap on creation.
An Example
private void myMethod()
{
Object myObject = new Object();
}
We're declaring a variable, so we get space on the stack frame. The type is an Object, so this value is going to be a pointer to the space on the heap that was allocated when the Object was created.
Variables contains only references to this objects and this references stored in stack in case of local variables, but data of objects the point to stored in heap.
You can read more, for example, here: link
method variables are stored in Stack. Objects , in the other hand are stored in the Heap as the image below demonstrates it.
That's why if you get StackOverFlowException, that means you have declared too many variables in a method or you are calling too many methods in a recursive call. And if you get Java Heap Space Error, that means you are creating more objects than you do.
For Stack and Heap explanation, I recommend this link
what happens in memory when I, say, do the following:
in C: char *c=NULL;
in java: MyClass mc=null;
what happens in memory, how is this null represented in memory in both of these languages? Thanks
In C you are basically setting the pointer to zero value. In fact
char *c = NULL;
is equivalent to
char *c = 0;
Zero pointer cannot be dereferenced since there is no memory mapping for this address. On platforms with virtual memory, an attempt to do so triggers a page fault transferring control to the operating system which then usually handles the situation by killing the offending process (in UNIX your process receives Segmentation Violation signal SIGSEGV).
In Java, all non-primitive type variables are references. null in Java is a literal denoting the only value of a special unnamed type. This type can be cast to any reference type allowing you to put null into any reference variable. An attempt to use such reference to access an object will throw an unchecked exception called NullPointerException. See JLS 3.10.7 and JLS 4.1 for details.
What you do here is assign a char pointer to NULL.
It has basically the same effect, with the huge difference that dereferencing NULL in C will make your program die with a SIGSEGV (well, under Unix-like OSes, including Linux and Mac OS X), while Java will throw a NullPointerException.
Note that mc is really a reference, not a class by itself. It is nearly the same as a C pointer.
NULL has some practical value in both cases anyway: you can test if (mc == null) in Java. In C, that would be a simple if (!p) (but if (p == NULL) also works).
You can find your answer in the following posts:
What exactly is null in Java memory
Java - Does null variable require space in memory
So basically, the null itself does not take space but the object being put equal to null does take space
NULL is a special value indicating there's no data at that location, it's specific representation can vary. in C it's just 0, i'm note sure about java.
In java, you cannot state an array's size in its declaration
int[5] scores; //bad
I'm told this is because the JVM does not allocate space in memory until an object is initialized.
If you have an instance array variable (auto initialized with a default value of null), does that variable point to a place in the heap indicating null?
A null reference is literally a zero-value. The operating system prevents any program from accessing the zero address in memory, so the JVM will proactively check and make sure that a reference value isn't zero before allowing you to access it. This lets the JVM give you a nice NullPointerException rather than a "The program has performed an Illegal Operation" crash.
So you could say that the variable "points to" an invalid heap location. Or you could just say the variable doesn't "point to" anything. At that point it's just a question of semantics.
No, because in the JVM there's no need for that.
If you're in a native language (C and C++, for instance), NULL is a pointer with a zero value, and that points to the memory base address. Obviously that's not a valid address, but you "can" dereference it anyway - especially in a system without protected memory, like old MS-DOS or small ones for embedded processors. Not that it would be a valid address - usually that location contains interrupt vectors and you shouldn't touch them. And of course in any modern OS that will raise a protection fault.
But in the JVM a reference to an object is more like a handle (i.e. an index in a table) and null is an 'impossible' value (an index that is outside the domain of the table), so it can't be dereferenced and doesn't occupy space in such table.
I think this post will answer your question - Java - Does null variable require space in memory
In Java, null is just a value that a reference (which is basically a
restricted pointer) can have. It means that the reference refers to
nothing. In this case you still consume the space for the reference.
This is 4 bytes on 32-bit systems or 8 bytes on 64-bit systems.
However, you're not consuming any space for the class that the
reference points to until you actually allocate an instance of that
class to point the reference at.
Edit: As far as the String, a String in Java takes 16 bits (2 bytes)
for each character, plus a small amount of book-keeping overhead,
which is probably undocumented and implementation specific.
(remember to upvote the answer in the link if it helps you out)
Nope...you'll have a null (0x00) reference in the object's variable.
I would argue that "int[5] scores; //bad" is not due to memory allocation.
Notice that when you declare something you are really declaring
Type ReferenceName = new Type()
typically.
Observe the two examples
int[] scores = new int[5];
JLabel label = new JLabel();
The types (on the left hand side) are int[] and JLabel, which have nothing to do with memory allocation (except for a pointer), while the new instances (on the right side, requiring memory allocation) are int[5], requiring space for 5 ints, and JLabel(), requiring no arguments to call the constructor, but memory enough for a JLabel.
I have two local variables in a method as follows,
int i=10;
String test="test";
As far as i know as these variables are local to only a specfic method,these should be stored on a stack,will the string type is also stored on a stack?
The variable itself (the reference to the String instance) will be stored on the stack.
The String instance (which contains the char[] with the actual data) will usually be stored in the heap. It is up to the JVM to optimize this, though. It could be a String from the permgen pool, or if escape analysis is done (and the String is guaranteed to not leave the local scope), it might choose to allocate it on the stack as well.
This is the case for all objects and arrays. Only primitives are different (because they are passed around as value, not as a reference to a data structure allocated elsewhere).
The stack frame will contain the value of the int and the (reference) value of the String. The object that the String reference value points (e.g. the thing that represents the string's characters, length and so on) to will be stored in the heap.
(It is probably easiest to explain this in a picture ... if someone could contribute a link ...)
As stated above, the reference will be on the stack. In Sun's JVM, the actual data would be stored in the perm gen area (since the String in question is a String literal), and would also be added to a weak HashMap which resides on the heap. This is the behavior for interned Strings in the Sun JVM.
Is pointer is just used for implementing java reference variable or how it is really implemented?
Below are the lines from Java language specification
4.3.1 Objects An object is a class instance or an array. The reference
values (often just references) are
pointers to these objects, and a
special null reference, which refers
to no object.
Does that mean it is pointer all the time?
In modern JVMs, references are implemented as an address.
Going back to the first version of HotSpot (and a bit earlier for the "classic VM"), references were implemented as handles. That is a fixed pointer to a pointer. The first pointer never changes for any particular object, but as the object data itself is moved the second pointer is changed. Obviously this impacts performance in use, but is easier to write a GC for.
In the latest builds of JDK7 there is support for "compressed oops". I believe BEA JRockit has had this for some time. Moving to 64 bit systems requires twice as much memory and hence bandwidth for addresses. "Compressed oops" takes advantage of the least significant three or four bits of address always being zero. 32 bits of data are shifted left three or four bits, allowing 32 or 64 GB of heap instead of 4 GB.
You can actually go and get the source code from here: http://download.java.net/jdk6/source/
The short answer to your question is: yes, there is a pointer to a memory location for your java variables (and a little extra). However this is a gigantic oversimplification. There are many many many C++ objects involved in moving java variables around in the VM. If you want to get dirty take a look at the hotspot\src\share\vm\oops package.
In practice none of this matters to developing java though, as you have no direct way of working with it (and secondly you wouldn't want to, the JVM is optimized for various processor architectures).
The answer is going to depend on every JVM implementation, but the best way to think of it is as a handle. It is a value that the JVM can look up in a table or some other such implementation the memory location of the reference. That way the JVM can move objects around in memory during garbage collection without changing the memory pointers everywhere.
A primitive type is always passed by value.
where as a Class Variable is actually a reference variable for the Object.
Consider a primitive type:
int i=0;
now the value of this primitive type is stored in a memory location of address 2068.
Every time you use this primitive type as a parameter, a new copy is created as it is not pass by reference but pass by value.
Now consider a class variable:
MyClass C1 = new MyClass();
Now this creates an object of the class type MyClass with a variable name C1.
The class variable C1 contains an address of the memory location of the object which is linked to the Valriable C1. So basically the class variable C1 points to the object location(new MyClass()).
And primitive types are stored in stack and objects in heaps.
Does that mean it is pointer all the time?
Yes, but it can't be manipulated as you normally do in C.
Bear in mind that being Java a different programming language that relies on its VM, this concept ( pointer ) should be used only as an analogy to understand better the behavior of such artifacts.