In Java, does it cost memory to declare a class level instance variable without initializing it?
For example: Does int i;
use any memory if I don't initialize it with i = 5;
?
Details:
I have a huge super-class that many different (not different enough to have their own super classes) sub-classes extend. Some sub-classes don't use every single primitive declared by the super-class. Can I simply keep such primitives as uninitialized and only initialize them in necessary sub-classes to save memory?
Yes. In your class level variables will assign to its default value even if you don't initialize them.
In this case you
int
variables will assign to0
and will occupied4 bytes
per each.Neither the Java Language Specification nor the Java Virtual Machine Specification specifies the answer to this because it's an implementation detail. In fact, JVMS §2.7 specifically says:
In theory, a conformant virtual machine could implement objects which have a lot of fields using set of bit flags to mark which fields have been set to non-default values. Initially no fields would be allocated, the flag bits would be all 0, and the object would be small. When a field is first set, the corresponding flag bit would be set to 1 and the object would be resized to make space for it. [The garbage collector already provides the necessary machinery for momentarily pausing running code in order to relocate live objects around the heap, which would be necessary for resizing them.]
In practice, this is not a good idea because even if it saves memory it is complicated and slow. Access to fields would require temporarily locking the object to prevent corruption due to multithreading; then reading the current flag bits; and if the field exists then counting the set bits to calculate the current offset of the wanted field relative to the base of the object; then reading the field; and finally unlocking the object.
So, no general-purpose Java virtual machine does anything like this. Some objects with an exorbitant number of fields might benefit from it, but even they couldn't rely on it, because they might need to run on the common virtual machines which don't do that.
A flat layout which allocates space for all fields when an object is first instantiated is simple and fast, so that is the standard. Programmers assume that objects are allocated that way and thus design their programs accordingly to best take advantage of it. Likewise, virtual machine designers optimize to make that usage fast.
Ultimately the flat layout of fields is a convention, not a rule, although you can rely on it anyway.
Yes, memory allocates though you are not assigning any value to it.
That takes
32 bit
memory (allocation). No matter you are using it or not.Again, no matter where you initialized, the memory allocates.
Only thing you need to take care is, just find the unused primitives and remove them.
Edit: Adding one more point that unlike primitive's references by default value is
null
, which carries a a memory ofAll members defined in your classes have default values, even if you don't initialize them explicitly, so they do use memory.
For example, every
int
will be initialized by default to0
, and will occupy4
bytes.For class members :
is the same as :
Here's what the JLS says about instance variables :
The original question talks about class level variables and the answer is that they do use space, but it's interesting to look at method scoped ones too.
Let's take a small example:
If we look at the bytecode generated:
Ok, as expected we assign a value at line 3 in the code, now if we change line 3 to (and remove the second println due to a compiler error):
... and check the bytecode then nothing is generated for line 3. So, the answer is that no memory is used at this point. In fact, the LSTORE occurs only on line 5 when we assign to the variable. So, declaring an unassigned method variable does not use any memory and, in fact, doesn't generate any bytecode. It's equivalent to making the declaration where you first assign to it.
In Java, when you declare a class attribute such as
String str;
, you are declaring a reference to an object, but it is not pointing yet to any object unless you affect a value to itstr=value;
. But as you may guess, the reference, even without pointing to a memory place, consumes itself some memory.