some thoughts on ClassValue

Peter Levart peter.levart at gmail.com
Sat Apr 27 15:46:17 PDT 2013


On 04/28/2013 12:31 AM, Peter Levart wrote:
>
> On 04/27/2013 11:54 PM, John Rose wrote:
>> On Apr 27, 2013, at 2:34 PM, Jochen Theodorou <blackdrag at gmx.org 
>> <mailto:blackdrag at gmx.org>> wrote:
>>
>>> Am 27.04.2013 23:26, schrieb John Rose:
>>> ...
>>>> Each instance of the Groovy runtime will use a distinct ClassValue 
>>>> instance.
>>>>
>>>> If the ClassValue instance goes dead, then all the values (for each
>>>> class) bound using that instance should go dead also.
>>>>
>>>> If they don't it's a bug.
>>>
>>> well... I assume that if I have a ClassValue for Object that is an
>>> isntance of Foo, that this instance will stay as long as I don't delete
>>> it myself. That is how ClassValue works, or not? And that is exactly my
>>> problem too.
>>
>> As a simple example:  Make a ClassValue object, bind a 1Mb array to 
>> Object.class using it, and then throw it all away.  (Except 
>> Object.class, naturally.)  Even if you do this in a loop, you should 
>> not get a storage leak.
>>
>> (A class value bound to a class is live only if both the Class and 
>> the ClassValue instance are both live.)
>>
>> Often people bind ClassValue instances to "static final" variables. 
>>  If the class containing the static variable goes away, then the 
>> ClassValue goes away, and anything bound (to whatever class, 
>> including Object) should go away.  That's nice, at least in theory.
>>
>> Things get tricky (this probably happens in practice) when there is a 
>> loop:
>>
>>   class MyRuntimeInMyClassLoader { static final MyClassValue MYCV = 
>> ... } => instance of MYCV
>>   instance of MYCV x Object.class (say) => instance of MyMetaStuff
>>   instance of MyMetaStuff => MyRuntimeInMyClassLoader.class
>>
>> Although I am not one of the 12 people on the planet who fully 
>> understand class loader interactions with GC, I suspect this loop 
>> might be "sticky", and might have to be broken by (say) a 
>> SoftReference.  (You can use a SoftReference if you are willing to 
>> have the GC break references not recently used, which you can 
>> reconstruct if needed.)
>>
>> --- John
>
> Hello John, Jochen, sorry to interrupt,
>
> So to break a loop, you propose the following structure if I 
> understand correctly?
>
> class MyRuntimeInMyClassLoader {
>     static final ClassValue<SoftReference<MyMetaStuff>> MYCV = new 
> ClassValue<>() {...};
>
>
> Wouldn't then MyRuntimeInMyClassLoader class be softly reachable (via 
> softly reachable MyMetaStuff) and might not go away so quickly until 
> there is memory pressure and consequently the MYCV ClassValue too?
>
>
> Regards, Peter

Perhaps the following could do:

class MyRuntimeInMyClassLoader {
     static final ClassValue<WeakReference<MyMetaStuff>> MYCV = new 
ClassValue<>() {...};
     // strongly reference all MyMetaStuff instances so they don't go away
     // until MyRuntimeInMyClassLoader goes away
     static final Vector<MyMetaStuff> metas = ...;

(idea taken from ClassLoader which retains it's Class objects in similar 
way)


Regards, Peter

>
>>
>>
>> _______________________________________________
>> 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/20130428/4f8a91e5/attachment.html 


More information about the mlvm-dev mailing list