On 04/29/2016 10:28 AM, Michael Haupt wrote:
<http://cr.openjdk.java.net/%7Emhaupt/8031043/> for a snapshot of what
is currently available.
We have three patches:
* Christian's, which simply reduces the HashMap size,
* Peter's, which refactors ClassValueMap into a WeakHashMap,
* mine, which attempts to introduce the single-value storage
optimisation John had suggested (I worked on performance with Aleksey
All of these are collected in the patches subdirectory for
convenience. (Peter, I adapted your patch to the new Unsafe location.)
I extended Peter's benchmark (thanks!) to cover single-value storage;
the source code is in the benchmark subdirectory, together with raw
results from running the benchmark with each of the three patches
applied. A results-only overview is in benchmark-results.txt.
The three are roughly on par. I'm not sure the single-value storage
optimisation improves much on footprint given the additional data that
must be kept around to make transition to map storage safe.
I must admit that my old patch is very complex, so I doubt anyone will
take time to review it. It is almost a clean-room re-implementation of
ClassValue API. My main motivation was footprint optimization for all
sizes - not just one value per class as I doubt this will be very common
situation anyway. Current ClassValue maintains 2 parallel hash-tables
per class. A WeakHashMap which is accessed with proper synchronization
and an optimized "cache" of entries for quick access. This makes it
consume almost 100 bytes per (Class, ClassValue) pair. I managed to
almost half the overhead for typical situation (1024 classes x 16
ClassValue(s)), but for the price of complexity.
Reviving this thread made me think about ClassValue again and I got
another idea. This is an experiment to see if ConcurrentHashMap could be
leveraged to implement ClassValue API with little added complexity:
And here are the results of a benchmark comparing JDK 9 original with
It is a little slower for random access of bigger sizes and #s of
classes. Most probably a consequence of reduced cache hit ratio as CHM
is a classical hash table with buckets implemented as linked list of
entries whereas jdk 9 ClassValue cache is a linear-scan hash table which
has better cache locality. This is particularly obvious in sequential
access where CHM behaves on-par. It's a pity that CHM has a
non-changeable load factor of 0.75 as changing this to 0.5 would most
certainly improve benchmark results for a little more memory.
Where this version excels is in footprint. I managed to more than half
the overhead. There's only a single ReferenceQueue needed and
consequently expunging of stale data is more prompt and thorough. The
code of ClassValue has been more than halved too.
What do you think?
Dr. Michael Haupt | Principal Member of Technical Staff
Phone: +49 331 200 7277 | Fax: +49 331 200 7561
OracleJava Platform Group | LangTools Team | Nashorn
Oracle Deutschland B.V. & Co. KG | Schiffbauergasse 14 | 14467
ORACLE Deutschland B.V. & Co. KG | Hauptverwaltung: Riesstraße 25,
Registergericht: Amtsgericht München, HRA 95603
Komplementärin: ORACLE Deutschland Verwaltung B.V. | Hertogswetering
163/167, 3543 AS Utrecht, Niederlande
Handelsregister der Handelskammer Midden-Nederland, Nr. 30143697
Geschäftsführer: Alexander van der Ven, Jan Schultheiss, Val Maher
Green Oracle <http://www.oracle.com/commitment> Oracle is committed
to developing practices and products that help protect the environment
mlvm-dev mailing list
mlvm-dev mailing list