[ http://issues.apache.org/jira/browse/XERCESC-1381?page=history ]
     
Khaled Noaman resolved XERCESC-1381:
------------------------------------

    Resolution: Fixed

Hi Christian,

I've committed your fix. Would you please verify? I've looked in the code for 
potential side effects, and I think that your fix is valid. When we cache 
grammars, we remove it from the grammar resolver table, so I agree with you 
that we should not change the table not to adopt elements.

Regards,
Khaled

> Memory Leak in GrammarResolver class
> ------------------------------------
>
>          Key: XERCESC-1381
>          URL: http://issues.apache.org/jira/browse/XERCESC-1381
>      Project: Xerces-C++
>         Type: Bug
>   Components: Validating Parser (Schema) (Xerces 1.5 or up only)
>     Versions: 2.6.0
>  Environment: all
>     Reporter: Christian Will
>  Attachments: GrammarResolver.cpp.patch
>
> Hi,
> the grammar resolver class produces memory leaks under some circumstances. If 
> we set the features fgXercesUseCachedGrammarInParse, 
> fgXercesCacheGrammarFromParse and lock the grammar pool all new created 
> grammars will never be deleted.
> Here is my first example. I create a parser, cache the grammar, lock the 
> grammar pool and parse one instance document. I delete the parser object, 
> unlock and delete the grammar pool, and terminate the platform utils. After 
> all objects are deleted we can see that still 3 kbytes are allocated from the 
> grammar pool memory manager.
> I could locate all allocations to [\internal\IGXMLScanner2.cpp(1146)].
> => "fDTDGrammar = new (fGrammarPoolMemoryManager) 
> DTDGrammar(fGrammarPoolMemoryManager);"
> Sample Log 1
> ------------
> init... 
> parser1 set feature 
> SchemaFullChecking,UseCachedGrammarInParse,CacheGrammarFromParse 
> PlatformUtils: 172842 [ 172842]bytes, 2855 [ 3918, 1162]blocks (0) 
> Parser One : 26456 [ 26456]bytes, 101 [ 101, 0]blocks (0) 
> GrammarPool : 1214 [ 1214]bytes, 20 [ 20, 0]blocks (0) 
> cache grammar... (T:/testfiles/_FIXML/schema/FIXML-main-4-4.xsd) 
> PlatformUtils: 172842 [ 172842]bytes, 2855 [ 3918, 1162]blocks (0) 
> Parser One : 26456 [ 308510]bytes, 101 [ 2885, 4064]blocks (5) 
> GrammarPool : 4239962 [ 12829334]bytes, 62711 [117134, 70374]blocks (8) 
> lock grammarpool... 
> PlatformUtils: 172842 [ 172842]bytes, 2855 [ 3918, 1162]blocks (0) 
> Parser One : 26456 [ 308510]bytes, 101 [ 2885, 4064]blocks (0) 
> GrammarPool : 5501456 [ 12829334]bytes, 97049 [151874, 70776]blocks (0) 
> --------------------------------------------------------------------------- 
> parse with parser1... (T:/testfiles/_FIXML/order100.xml) 
> PlatformUtils: 172842 [ 172842]bytes, 2855 [ 3918, 1162]blocks (0) 
> Parser One : 50846 [ 308510]bytes, 517 [ 3395, 4370]blocks (40) 
> GrammarPool : 5504580 [ 12829334]bytes, 97064 [151889, 70776]blocks (4) 
> --------------------------------------------------------------------------- 
> delete parser1... 
> PlatformUtils: 172842 [ 172842]bytes, 2855 [ 3918, 1162]blocks (0) 
> GrammarPool : 5504580 [ 12829334]bytes, 97064 [151889, 70776]blocks (0) 
> unlock grammarPool... 
> PlatformUtils: 172842 [ 172842]bytes, 2855 [ 3918, 1162]blocks (0) 
> GrammarPool : 4243086 [ 12829334]bytes, 62726 [151889,105114]blocks (0) 
> delete grammarPool... 
> PlatformUtils: 172842 [ 172842]bytes, 2855 [ 3918, 1162]blocks (0) 
> GrammarPool : 3020 [ 12829334]bytes, 12 [151889,176419]blocks (0) 
> terminate PlatformUtils... 
> GrammarPool : 3020 [ 12829334]bytes, 12 [151889,176419]blocks (0) 
> done. 
> ==-still-allocated-memory-=================================================
> pointer: 3df83c0 size: 44bytes sequence: 151875 
> T:\xerces_cvs\src\xercesc\util\XMemory.cpp(66) 
> T:\xerces_cvs\src\xercesc\internal\IGXMLScanner2.cpp(1146) 
> T:\xerces_cvs\src\xercesc\internal\IGXMLScanner.cpp(188) 
> T:\xerces_cvs\src\xercesc\internal\XMLScanner.cpp(434) 
> pointer: 3df86d0 size: 32bytes sequence: 151876 
> T:\xerces_cvs\src\xercesc\util\XMemory.cpp(66) 
> T:\xerces_cvs\src\xercesc\validators\DTD\DTDGrammar.cpp(169) 
> T:\xerces_cvs\src\xercesc\internal\IGXMLScanner2.cpp(1146) 
> T:\xerces_cvs\src\xercesc\internal\IGXMLScanner.cpp(188) 
> pointer: 3df87d8 size: 436bytes sequence: 151877 
> ..\..\..\..\..\src\xercesc/util/NameIdPool.c(122) 
> T:\xerces_cvs\src\xercesc\validators\DTD\DTDGrammar.cpp(169) 
> T:\xerces_cvs\src\xercesc\internal\IGXMLScanner2.cpp(1146) 
> T:\xerces_cvs\src\xercesc\internal\IGXMLScanner.cpp(188) 
> pointer: 3df8a70 size: 512bytes sequence: 151878 
> ..\..\..\..\..\src\xercesc/util/NameIdPool.c(136) 
> T:\xerces_cvs\src\xercesc\validators\DTD\DTDGrammar.cpp(169) 
> T:\xerces_cvs\src\xercesc\internal\IGXMLScanner2.cpp(1146) 
> T:\xerces_cvs\src\xercesc\internal\IGXMLScanner.cpp(188) 
> pointer: 3df8d58 size: 32bytes sequence: 151879 
> T:\xerces_cvs\src\xercesc\util\XMemory.cpp(66) 
> T:\xerces_cvs\src\xercesc\validators\DTD\DTDGrammar.cpp(173) 
> T:\xerces_cvs\src\xercesc\internal\IGXMLScanner2.cpp(1146) 
> T:\xerces_cvs\src\xercesc\internal\IGXMLScanner.cpp(188) 
> pointer: 3df8e60 size: 436bytes sequence: 151880 
> ..\..\..\..\..\src\xercesc/util/NameIdPool.c(122) 
> T:\xerces_cvs\src\xercesc\validators\DTD\DTDGrammar.cpp(173) 
> T:\xerces_cvs\src\xercesc\internal\IGXMLScanner2.cpp(1146) 
> T:\xerces_cvs\src\xercesc\internal\IGXMLScanner.cpp(188) 
> pointer: 3df90f8 size: 512bytes sequence: 151881 
> ..\..\..\..\..\src\xercesc/util/NameIdPool.c(136) 
> T:\xerces_cvs\src\xercesc\validators\DTD\DTDGrammar.cpp(173) 
> T:\xerces_cvs\src\xercesc\internal\IGXMLScanner2.cpp(1146) 
> T:\xerces_cvs\src\xercesc\internal\IGXMLScanner.cpp(188) 
> pointer: 3df93e0 size: 32bytes sequence: 151882 
> T:\xerces_cvs\src\xercesc\util\XMemory.cpp(66) 
> T:\xerces_cvs\src\xercesc\validators\DTD\DTDGrammar.cpp(174) 
> T:\xerces_cvs\src\xercesc\internal\IGXMLScanner2.cpp(1146) 
> T:\xerces_cvs\src\xercesc\internal\IGXMLScanner.cpp(188) 
> pointer: 3df94e8 size: 436bytes sequence: 151883 
> ..\..\..\..\..\src\xercesc/util/NameIdPool.c(122) 
> T:\xerces_cvs\src\xercesc\validators\DTD\DTDGrammar.cpp(174) 
> T:\xerces_cvs\src\xercesc\internal\IGXMLScanner2.cpp(1146) 
> T:\xerces_cvs\src\xercesc\internal\IGXMLScanner.cpp(188) 
> pointer: 3df9780 size: 512bytes sequence: 151884 
> ..\..\..\..\..\src\xercesc/util/NameIdPool.c(136) 
> T:\xerces_cvs\src\xercesc\validators\DTD\DTDGrammar.cpp(174) 
> T:\xerces_cvs\src\xercesc\internal\IGXMLScanner2.cpp(1146) 
> T:\xerces_cvs\src\xercesc\internal\IGXMLScanner.cpp(188) 
> pointer: 3df9a68 size: 24bytes sequence: 151885 
> T:\xerces_cvs\src\xercesc\util\XMemory.cpp(66) 
> T:\xerces_cvs\src\xercesc\validators\DTD\DTDGrammar.cpp(177) 
> T:\xerces_cvs\src\xercesc\internal\IGXMLScanner2.cpp(1146) 
> T:\xerces_cvs\src\xercesc\internal\IGXMLScanner.cpp(188) 
> pointer: 3df9b60 size: 12bytes sequence: 151886 
> ..\..\..\..\..\src\xercesc/util/XMLString.hpp(1667) 
> T:\xerces_cvs\src\xercesc\validators\DTD\XMLDTDDescriptionImpl.cpp(59) 
> T:\xerces_cvs\src\xercesc\validators\DTD\DTDGrammar.cpp(177) 
> T:\xerces_cvs\src\xercesc\internal\IGXMLScanner2.cpp(1146) 
> ==-still-allocated-memory-=================================================
> My second example shows the impact a little bit better. I lock the grammar 
> pool without loading the grammar. I parse the instance document 3 times. And 
> after I delete all objects and terminate the platform utils I can see that 
> the associated grammar is still 3 times (11.5MB) in memory.
> Sample Log 2
> ------------
> init... 
> parser1 set feature 
> SchemaFullChecking,UseCachedGrammarInParse,CacheGrammarFromParse 
> PlatformUtils: 172842 [ 172842]bytes, 2855 [ 3918, 1162]blocks (0) 
> Parser One : 26456 [ 26456]bytes, 101 [ 101, 0]blocks (0) 
> GrammarPool : 1214 [ 1214]bytes, 20 [ 20, 0]blocks (0) 
> lock grammarpool... 
> PlatformUtils: 172842 [ 172842]bytes, 2855 [ 3918, 1162]blocks (0) 
> Parser One : 26456 [ 26456]bytes, 101 [ 101, 0]blocks (0) 
> GrammarPool : 23934 [ 24098]bytes, 597 [ 629, 32]blocks (0) 
> --------------------------------------------------------------------------- 
> parse with parser1... (T:/testfiles/_FIXML/order100.xml) 
> PlatformUtils: 172842 [ 172842]bytes, 2855 [ 3918, 1162]blocks (0) 
> Parser One : 50862 [ 486594]bytes, 517 [ 3392, 4374]blocks (40) 
> GrammarPool : 4265794 [ 12855178]bytes, 63302 [117757, 70406]blocks (5) 
> parse with parser1... (T:/testfiles/_FIXML/order100.xml) 
> PlatformUtils: 172842 [ 172842]bytes, 2855 [ 3918, 1162]blocks (0) 
> Parser One : 52466 [ 497174]bytes, 586 [ 6317, 8535]blocks (65) 
> GrammarPool : 8120878 [ 16710262]bytes,115564 [224426,140764]blocks (0) 
> parse with parser1... (T:/testfiles/_FIXML/order100.xml) 
> PlatformUtils: 172842 [ 172842]bytes, 2855 [ 3918, 1162]blocks (0) 
> Parser One : 54586 [ 498778]bytes, 655 [ 9241, 12695]blocks (144) 
> GrammarPool : 11975962 [ 20565346]bytes,167826 [331095,211122]blocks (0) 
> --------------------------------------------------------------------------- 
> delete parser1... 
> PlatformUtils: 172842 [ 172842]bytes, 2855 [ 3918, 1162]blocks (0) 
> GrammarPool : 11975962 [ 20565346]bytes,167826 [331095,211122]blocks (0) 
> unlock grammarPool... 
> PlatformUtils: 172842 [ 172842]bytes, 2855 [ 3918, 1162]blocks (0) 
> GrammarPool : 11953242 [ 20565346]bytes,167249 [331095,211699]blocks (0) 
> delete grammarPool... 
> PlatformUtils: 172842 [ 172842]bytes, 2855 [ 3918, 1162]blocks (0) 
> GrammarPool : 11565252 [ 20565346]bytes,156786 [331095,222162]blocks (0) 
> terminate PlatformUtils... 
> GrammarPool : 11565252 [ 20565346]bytes,156786 [331095,222162]blocks (0) 
> Let me try to explain why this is happening. In GrammarResolver::putGrammar() 
> can we see that we put our grammar in the table 'fGrammarBucket' if we don't 
> want to cache our grammar or the grammar pool doesn't want cache our grammar 
> (because it is locked).
> void GrammarResolver::putGrammar(Grammar* const grammarToAdopt)
> {
> ...
>     if (!fCacheGrammar || !fGrammarPool->cacheGrammar(grammarToAdopt))
>     {
>         // either we aren't caching or the grammar pool doesn't want it
>         // so we need to look after it
>         fGrammarBucket->put( (void*) 
> grammarToAdopt->getGrammarDescription()->getGrammarKey(), grammarToAdopt );
>         if (grammarToAdopt->getGrammarType() == Grammar::SchemaGrammarType)
>         {
>             fGrammarsToAddToXSModel->addElement((SchemaGrammar*) 
> grammarToAdopt);
>         }
>     }
> }
> So far so good. We have all grammars that we don't want to cache or/and can't 
> be cached in this table. So normaly if it deletes the table fGrammarBucket 
> all grammars will be deleted. But if the feature 
> fgXercesCacheGrammarFromParse is set it changes the behavior of the table to 
> not adopte the elements. What we can see in 
> GrammarResolver::cacheGrammarFromParse().
> void GrammarResolver::cacheGrammarFromParse(const bool aValue)
> {
>     reset();
>     fCacheGrammar = aValue;    
>     fGrammarBucket->setAdoptElements(!fCacheGrammar);
> }
> I think that is wrong to change the property of our table to not adopt the 
> elements. Whenever we remove an grammar from our list, for example to cache 
> to grammar, we call fGrammarBucket->orphanKey(grammarKey), and that means 
> already that we remove the grammar wihtout deleting it.
> I removed this line "fGrammarBucket->setAdoptElements(!fCacheGrammar);" made 
> some tests and everything looks good.
> But I'm not sure if there are no side effects. And that is the reason why I 
> would like to get a second opinion from somebody. I can also send parts of my 
> code If you have problems to reproduce the bug.
> Regards,
> Christian Will

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
If you want more information on JIRA, or have a bug to report see:
   http://www.atlassian.com/software/jira


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to