IdentityHashMap & natStackTrace

Ranjit Mathew rmathew@gmail.com
Fri Nov 26 06:53:00 GMT 2004


Rutger Ovidius wrote:

> public Object put(Object key, Object value)
>        ...
>        if (size > threshold) {
>           table = new Object[old.length << 1 + 2];
[...]
> These two issues seem to be a burden on the heap.  I can drop ~400k of
> ram by doubling the size of this instead of using "old.length << 1 +
> 2" during each table expansion.

Good catch!

As Chris points, due to operator precedence weirdness this
becomes a left shift by 3 or multiplication by 2^3, in line
with what you observed.

This was introduced almost two years ago in a merge from
Classpath:

http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libjava/java/util/IdentityHashMap.java.diff?r1=1.8&r2=1.9&only_with_tag=MAIN

Relevant change:

  // This isn't necessarily prime, but it is an odd number of key/value
  // slots, which has a higher probability of fewer collisions.
- table = new Object[old.length * 2 + 2];
+ table = new Object[old.length << 1 + 2];

I think this is surely a bug - the comment above this line
didn't hold earlier and doesn't hold now - we still have
an even number of slots.  (I don't have my Knuth handy right
now, but surely there must be a simple method of calculating
the nearest prime to (old.length * 2)...)

You should either file a bug or submit a patch fixing
this issue.


> This implementation fills the array with emptyslot (Arrays.fill),
> which uses a whole bunch of memory. Can't a guard be used on lookups
> instead of actually filling this in (checking equality with
> emptyslot)?

Can you elaborate on that?  Note that a NULL can't be used and
"emptyslot" is a reference to the same sentinel Object.

Thanks,
Ranjit.

-- 
Ranjit Mathew          Email: rmathew AT gmail DOT com

Bangalore, INDIA.      Web: http://ranjitmathew.tripod.com/



More information about the Java mailing list