You generally need to reserve at least a pointer sized block of memory for a Java object because they can be used as locks with the sychronized keyword. Very few objects ever get used as a lock, so they make use of the bytes for other things like the hash.
Of course, that does imply the synchronized keyword has a fairly substantial memory cost.
Of course, that does imply the synchronized keyword has a fairly substantial memory cost.