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