Why is Java's boolean primitive size not defined?
Short answer: yes, boolean values are manipulated as 32-bit entities, but arrays of booleans use 1 byte per element.
Longer answer: the JVM uses a 32-bit stack cell, used to hold local variables, method arguments, and expression values. Primitives that are smaller than 1 cell are padded out, primitives larger than 32 bits (long and double) take 2 cells. This technique minimizes the number of opcodes, but does have some peculiar side-effects (such as the need to mask bytes).
Primitives stored in arrays may use less than 32 bits, and there are different opcodes to load and store primitive values from an array. Boolean and byte values both use the baload
and bastore
opcodes, which implies that boolean arrays take 1 byte per element.
As far as in-memory object layout goes, this is covered under the "private implementation" rules, it can be 1 bit, 1 byte, or as another poster noted, aligned to a 64-bit double-word boundary. Most likely, it takes the basic word size of the underlying hardware (32 or 64 bits).
As far as minimizing the amount of space that booleans use: it really isn't an issue for most applications. Stack frames (holding local variables and method arguments) aren't very large, and in the big scheme a discrete boolean in an object isn't that large either. If you have lots of objects with lots of booleans, then you can use bit-fields that are managed via your getters and setters. However, you'll pay a penalty in CPU time that is probably bigger than the penalty in memory.
A single boolean somewhere in the inheritance hierarchy can use up to 8 bytes! This is due to padding. More details can be found in How much memory is used by my Java object?:
Coming back to the question of how much a boolean consumes, yes it does consume at least one byte, but due to alignment rules it may consume much more. IMHO it is more interesting to know that a boolean[] will consume one byte per entry and not one bit,plus some overhead due to alignment and for the size field of the array. There are graph algorithms where large fields of bits are useful, and you need to be aware that, if you use a boolean[] you need almost exactly 8 times more memory than really needed (1 byte versus 1 bit).
The 5th Edition of Java in a Nutshell (O'Reilly) says a boolean primitive type is 1 byte. That could be wrong, based on what the examination of the heap is showing. I wonder if most JVMs have issues with allocating less than a byte for variables.