RFR (M) 8164921: Memory leaked when instrumentation.retransformClasses() is called repeatedly

Coleen Phillimore coleen.phillimore at oracle.com
Tue Oct 4 14:31:48 UTC 2016



On 10/3/16 7:11 PM, serguei.spitsyn at oracle.com wrote:
> Coleen,
>
>
> On 10/3/16 08:46, Coleen Phillimore wrote:
>>
>> Serguei, thank you for looking at this.
>>
>> On 9/30/16 7:57 PM, serguei.spitsyn at oracle.com wrote:
>>> Hi Coleen,
>>>
>>>
>>> Just wanted to share a couple of comments I have so far.
>>>
>>>
>>> http://cr.openjdk.java.net/~coleenp/8164921.01/webrev/src/share/vm/memory/metaspace.cpp.frames.html
>>>
>>> 302 debug_only(GrowableArray<Metablock*>* _all_blocks);
>>> 855 DEBUG_ONLY(_all_blocks = new (ResourceObj::C_HEAP, mtClass) 
>>> GrowableArray<Metablock*>(100, true)); 863 DEBUG_ONLY(delete 
>>> _all_blocks;) 891 
>>> DEBUG_ONLY(_all_blocks->remove((Metablock*)new_block)); 908 
>>> DEBUG_ONLY(_all_blocks->remove((Metablock*)free_block)); 922 
>>> DEBUG_ONLY(_all_blocks->remove((Metablock*)new_block));
>>>   Not clear, why different macros debug_only() is used at L302.   
>>> Could it be DEBUG_ONLY as well?
>> Yes, good catch.  I thought I had recompiled after adding the 
>> DEBUG_ONLY, but I must not have.  It should be DEBUG_ONLY.
>>>   866 void BlockFreelist::return_block(MetaWord* p, size_t word_size) {
>>>   867   Metablock* free_chunk = ::new (p) Metablock(word_size);
>>> 868 if (word_size < SmallBlocks::small_block_min_size()) {
>>> 869 // Dark matter
>>> 870 return; 871 } else if (word_size < 
>>> SmallBlocks::small_block_max_size()) {
>>>  In case of dark matter the free_chunk is leaked.  It is better to 
>>> rearrange the fragment to something like this:
>>>   void BlockFreelist::return_block(MetaWord* p, size_t word_size) {
>>> if (word_size < SmallBlocks::small_block_min_size()) {
>>> return; // Dark matter
>>> }
>>> Metablock* free_chunk = ::new (p) Metablock(word_size); if 
>>> (word_size < SmallBlocks::small_block_max_size()) {
>> Okay, yes, this seems like it would be a bug since 
>> SmallBlocks::small_block_min_size() should equal sizeof Metablock in 
>> words, but since we align up to sizeof Metablock during allocation, 
>> we won't ever hit this.   But I'll change as suggested. 
>
>
> I agree, we won't hit it.
> But it is still better to make it right.
> Thank you for the update!

Okay, I fixed this as suggested.
>
>
>
>
>>>   886 MetaWord* BlockFreelist::get_block(size_t word_size) {
>>> 887 if (word_size < SmallBlocks::small_block_max_size() && 
>>> small_blocks()->list_at(word_size).count() > 0) {
>>>   . . .
>>> 892 return new_block;
>>> 893 }
>>> 894
>>> 895 if (word_size < BlockFreelist::min_size()) {
>>>   896     // Dark matter.  Too small for dictionary.
>>>   897     return NULL;
>>>   898   }
>>>   It'd be better to reorder the fragments 887-893 and 895-898. 
>>> Thanks, Serguei
>> The order is important because we first try for something in the 
>> small_blocks array, then try for something in the dictionary. 
>> BlockFreelist::min_size() is the size of a minimal dictionary entry, 
>> not the same as SmallBlocks::small_block_min_size(). So the code is, 
>> look for something in the small blocks (3-11 words) but if the size 
>> is too small for the dictionary (12 words), return.  Then the block 
>> is allocated from the Metachunk and not the small_blocks/dictionary 
>> of returned blocks. Thank you for starting your review.  Please let 
>> me know when you have further comments. Coleen 
>
>
> Ok, thank you for explanation.
> But then the additional check is needed before the L886:
>
>   if (word_size < SmallBlocks::small_block_min_size()) {
>     return;
>   }
>
> Otherwise, we can hit the assert in the list_at():
>
> 278 FreeList<Metablock>& list_at(size_t word_size) {
> 279 assert(word_size >= _small_block_min_size, "There are no metaspace 
> objects less than %u words", _small_block_min_size);
> 280 return _small_lists[word_size - _small_block_min_size];
> 281 }

I also added this as suggested.

Thanks, Serguei!
Coleen
> I do not have any other comments.
> Reviewed.
>
>
> Thanks,
> Serguei
>
>
>>> On 9/30/16 12:02, Coleen Phillimore wrote:
>>>> Summary: Return Metablocks smaller than dictionary's dark matter. 
>>>> This change contributed by Jon Masamitsu and myself.  To reclaim 
>>>> "dark matter" this change adds an array of small blocks by size, 
>>>> created lazily, to return Metablocks smaller than the 
>>>> BinaryTreeDictionary entry's minimum size.   This change also fixed 
>>>> a bug in small object double free and adds debugging code to check 
>>>> for this case. With this change, the submitted test case runs 
>>>> indefinitely.   Also passed rbt tier 1-5 testing. open webrev at 
>>>> http://cr.openjdk.java.net/~coleenp/8164921.01/webrev bug link 
>>>> https://bugs.openjdk.java.net/browse/JDK-8164921 Thanks, Coleen and 
>>>> Jon 
>



More information about the hotspot-dev mailing list