On 05/03/2015 11:10 AM, Remi Forax wrote:
Hi Peter,
computeValue() may recursively call get() by example to crawle the
inheritance hierarchy so i am not sure a lock is a good idea here
because in that case, it usually takes several millis to complete the
to level computeValue.
regards,
Rémi
In that case coputeValue() must be called without lock held and then the
result CAS-ed. As said, this option is simple to get and the change is
localized to ClassValue$Entry methods:
http://cr.openjdk.java.net/~plevart/misc/ClassValue.Alternative/webrev.02/
Regards, Peter
P.S.
Are you also experiencing problems accessing links on
cr.openjdk.java.net ? I get 404 - Not Found on any URL for 2 days now...
SFTP works though, so I'm making these http URLs up from the sftp URLs.
Hope this get fixed soon.
On 05/03/2015 12:32 AM, Peter Levart wrote:
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
_______________________________________________
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