tags:

views:

1155

answers:

9

The Java Virtual Machine Specification says that there is limited support for boolean primitive types.

There are no Java virtual machine instructions solely dedicated to operations on boolean values. Instead, expressions in the Java programming language that operate on boolean values are compiled to use values of the Java virtual machine int data type.

The above implies (although I may have misinterpreted it) that the int data type is used when operating on booleans, but this is a 32 bit memory construct. Given that a boolean only represents 1 bit of information:

  • Why is a byte, or short, type not used as the proxy for a boolean instead of int?
  • For any given JVM what's the most reliable way of finding out exactly how much memory is used to store a boolean type?
A: 

For the memory usage take a heap dump of a running program and then inspect it.

Robert Munteanu
+1  A: 

The boolean mapping was done with a 32bit CPU in mind. The int value has 32 bits so it can be processed in one operation.

Here's a solution from Peter Norvig's Java IAQ: Infrequently Answered Questions to measure the size (with some imprecision):

static Runtime runtime = Runtime.getRuntime();
...
long start, end;
Object obj;
runtime.gc();
start = runtime.freememory();
obj = new Object(); // Or whatever you want to look at
end =  runtime.freememory();
System.out.println("That took " + (start-end) + " bytes.");
Thomas Jung
+1  A: 

There are some interesting comments relating to this here.

Richard
Yes, this is interesting, so +1; (but it is with reference to the java.lang.Boolean object not boolean primitive)
Joel
+2  A: 

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).

Adrian
How would use a boolean[] anyway?
Thomas Jung
boolean[] could be used for a mask. Sometimes a BitSet can be better though, because it has some useful methods.
Michael Munsey
+9  A: 

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.

kdgregory
Are you sure about the 1 bit in a boolean array?
Thomas Jung
I believe I wrote "byte". It's definitely "byte" now, although it's possible that my earlier edit used "bit".
kdgregory
@kdgregory For boolean/byte class members, is it also true, that they are also 4 bytes? The class instance is allocated as a whole on the stack, so I can imagine, JVM should probably use 1 byte per boolean/byte member and finally make an 4-byte alignment for the complete class instance. Is it so? (if you have references that prove this, please, share)
dma_k
@dma_k: as noted in my response, the layout of a class instance is implementation dependent. However, note that class instances are not stored in the stack, they're stored on the heap (although you'll see some references to JDK 7 "escape analysis" moving objects from stack to heap, this appears not to be the case; see java.sun.com/javase/7/docs/technotes/guides/vm/…)
kdgregory
+1  A: 

Refer to the answer given by jon skeet link text

Warrior
Damn, I missed the duplicate.
Joel
+1  A: 

CPUs operate on a specific datatype length. In case of 32bit CPUs they are 32 bits long and therefore what you call 'int' in Java. Everything below or above that must be filled or splitted to this length before the CPU can process it. This doesn't take much time, but if you need 2 CPU cycles instead of 1 for basic operations, this means doubled costs/time.

This spec is dedicated for 32bit CPUs so that they can process booleans with their native datatype.

You can only have one here: speed or memory - SUN decided for speed.

Hardcoded
A: 

Why not make one .java file like this:

Empty.java

class Empty{
}

and one class like this:

NotEmpty.java

class NotEmpty{
   boolean b;
}

Compile them both and compare the .class files with a hex editor.

Pete
this is another metric altogether, unrelated to sizing the primitive boolean type in memory.
Joel
A: 

The 5th Edition of Java in a Nutshell (O'Reilly) says a boolean primitive type is 1 bit. 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.

Matthew Flynn