This has caught my interest and attention since yesterday. I am trying to store bits in Java and hit by Memory Overhead.
My first question regarding same is What is size of my Bitset?
Based on the answers I looked at other references and found Memory Usage guide.
Then I looked at BitSet
source code which looks like
public class BitSet implements Cloneable, java.io.Serializable {
/*
* BitSets are packed into arrays of "words." Currently a word is
* a long, which consists of 64 bits, requiring 6 address bits.
* The choice of word size is determined purely by performance concerns.
*/
private final static int ADDRESS_BITS_PER_WORD = 6;
private final static int BITS_PER_WORD = 1 << ADDRESS_BITS_PER_WORD;
private final static int BIT_INDEX_MASK = BITS_PER_WORD - 1;
/* Used to shift left or right for a partial word mask */
private static final long WORD_MASK = 0xffffffffffffffffL;
/**
* @serialField bits long[]
*
* The bits in this BitSet. The ith bit is stored in bits[i/64] at
* bit position i % 64 (where bit position 0 refers to the least
* significant bit and 63 refers to the most significant bit).
*/
private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("bits", long[].class),
};
/**
* The internal field corresponding to the serialField "bits".
*/
private long[] words;
/**
* The number of words in the logical size of this BitSet.
*/
private transient int wordsInUse = 0;
/**
* Whether the size of "words" is user-specified. If so, we assume
* the user knows what he's doing and try harder to preserve it.
*/
private transient boolean sizeIsSticky = false;
/* use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = 7997698588986878753L;
/**
* Given a bit index, return word index containing it.
*/
private static int wordIndex(int bitIndex) {
return bitIndex >> ADDRESS_BITS_PER_WORD;
}
.....
}
As per the calculation based on Memory Guide
, this is what I calculated
8 Bytes: housekeeping space
12 Bytes: 3 ints
8 Bytes: long
12 Bytes: long[]
4 Bytes: transient int // does it count?
1 Byte : transient boolean
3 Bytes: padding
This sums to 45 + 3 bytes (padding to reach multiple of 8)
This means an empty BitSet
itself reserves 48 bytes
.
But my requirement was to store bits, What am I missing? What are my options here?
Thanks much
UPDATE
My requirement is that I want to store total of 64 bits
in two separate fields
class MyClass{
BitSet timeStamp
BitSet id
}
and I want to store millions of MyClass
objects in memory