ClassValue perf?
Peter Levart
peter.levart at gmail.com
Sun May 3 21:47:13 UTC 2015
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
>>>> <headius at headius.com <mailto:headius at headius.com>>:
>>>>
>>>> On Mon, Apr 27, 2015 at 12:50 PM, Jochen Theodorou
>>>> <blackdrag at gmx.org <mailto:blackdrag at 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 at openjdk.java.net
>>> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
>>
>>
>>
>> _______________________________________________
>> mlvm-dev mailing list
>> mlvm-dev at openjdk.java.net
>> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
>
>
>
> _______________________________________________
> mlvm-dev mailing list
> mlvm-dev at openjdk.java.net
> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/mlvm-dev/attachments/20150503/74d35fa7/attachment.html>
More information about the mlvm-dev
mailing list