Hi,
I have considered using ClassValue in the past because it is quite fast
(as fast as a hash table can be) but was afraid of footprint overhead,
because I saw with debugger a structure being grown before my eyes that
was quite complicated and that I could not understand entirely. Now I
took some time to actually try to understand and measure it. In a
typical scenario ClassValue was designed for (initial capacity == 32),
initializing for example 16 ClassValues x 1024 Classes, jmap shows the
following interesting entries which all amount to overhead (that's on
64bit JVM with compressed OOPS):
num #instances #bytes class name
----------------------------------------------
1: 16384 655360 java.util.WeakHashMap$Entry
2: 16402 524864 java.lang.ClassValue$Entry
8: 1024 147456 [Ljava.util.WeakHashMap$Entry;
9: 1025 147480 [Ljava.lang.ClassValue$Entry;
13: 1024 65536 java.lang.ClassValue$ClassValueMap
17: 1024 32768 java.lang.ref.ReferenceQueue
21: 1024 16384 java.lang.ref.ReferenceQueue$Lock
----------------------------------------------
Total: 1589848 (97 bytes/entry)
ClassValueMap is a WeakHashMap subclass which contains an array of
WeakHashMap$Entry objects. In addition it maintains a parallel "cache"
array of ClassValue$Entry objects. Both of those entry objects are
WeakReferences. It means that each (Class,ClassValue) pair needs 2
WeakReferences (with additional fields) and 2 array slots to hold
associated value.
So I wondered, would it be possible to simplify CV and make it more
straight-forward by taking away almost half of overhead to get this:
num #instances #bytes class name
----------------------------------------------
1: 16384 655360 java.lang.ClassValue$Entry
7: 1024 147456 [Ljava.lang.ClassValue$Entry;
13: 1024 40960 java.lang.ClassValue$ClassValueMap
15: 1024 32768 java.lang.ref.ReferenceQueue
19: 1024 16384 java.lang.ref.ReferenceQueue$Lock
----------------------------------------------
Total: 892928 (54 bytes/entry)
I tried and came up with the following:
http://cr.openjdk.java.net/~plevart/misc/ClassValue.Alternative/webrev.01/
It was not easy to keep the performance approximately on the same level
while re-designing the implementation. But I think I managed to get it
to perform mostly the same for the fast-path case. This alternative
implementation also guarantees that, unless remove() is used,
computeValue() is called exactly once per (Class, ClassValue) pair.
Original implementation explains that it can redundantly compute more
than one value and then throw away all but one. This alternative
implementation could easily be modified to do the same (using CAS
instead of lock) if anyone is afraid of deadlocks.
Here's a micro benchmark with results measuring original vs. alternative
implementation. Attached results are for JDK9 on Intel i7 / Linux box
using 4 concurrent threads for tests:
http://cr.openjdk.java.net/~plevart/misc/ClassValue.Alternative/ClassValueBench.java
It would be interesting to see if and how it works for you too (just
compile and prepend to bootclasspath).
Regards, Peter
On 04/30/2015 03:57 PM, Michael Haupt wrote:
Hi,
I'm looking at JDK-8031043 and would appreciate if you guys could send
any code you think might benefit from a smaller initial CV memory
footprint my way. Given what I've read, it could have some impact
during startup (Groovy?) if the value is reduced to 1.
Best,
Michael
Am 30.04.2015 um 15:43 schrieb Charles Oliver Nutter
<head...@headius.com <mailto:head...@headius.com>>:
On Mon, Apr 27, 2015 at 12:50 PM, Jochen Theodorou <blackd...@gmx.org
<mailto:blackd...@gmx.org>> wrote:
Am 27.04.2015 19:17, schrieb Charles Oliver Nutter:
Jochen: Is your class-to-metaclass map usable apart from the Groovy
codebase?
Yes. Look for
org.codehaus.groovy.reflection.GroovyClassValuePreJava7 which
is normally wrapped by a factory.
Excellent, thank you!
- Charlie
--
Oracle <http://www.oracle.com/>
Dr. Michael Haupt | Principal Member of Technical Staff
Phone: +49 331 200 7277 | Fax: +49 331 200 7561
OracleJava Platform Group | HotSpot Compiler Team
Oracle Deutschland B.V. & Co. KG, Schiffbauergasse 14 | 14467 Potsdam,
Germany
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@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
_______________________________________________
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev