[ 
https://issues.apache.org/jira/browse/KARAF-5395?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16185524#comment-16185524
 ] 

Robert Varga commented on KARAF-5395:
-------------------------------------

I agree it is not going to be easy. I have tested your patch, but unfortunately 
it does not make a real dent in memory usage -- heap usage is dominated by 
felix resolver internal structures.

I think CapabilityImpl and RequirementImpl are pretty trivial to fix, 
ResourceImpl is sticky in this regard. Luckily Resource.equals() is defined 
quite vaguely, so capturing those extra requirements for fine-grained control 
should be possible to implement without falling back to indentity 
hashCode/equals.

Essentially I have two features:

{quote}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<features xmlns="http://karaf.apache.org/xmlns/features/v1.4.0"; 
name="odl-sxp-api">
    
<repository>mvn:org.opendaylight.mdsal.model/odl-mdsal-models/0.11.0/xml/features</repository>
    
<repository>mvn:org.opendaylight.yangtools/odl-yangtools-common/1.2.0/xml/features</repository>
    <feature name="odl-sxp-api" description="Feature :: OpenDaylight :: Sxp :: 
Api" version="1.5.0">
        <details>OpenDaylight is leading the transformation to Open Software 
Defined Networking (SDN). For more information, please see 
https://www.opendaylight.org</details>
        <feature version="0.11.0" prerequisite="false" 
dependency="false">odl-mdsal-models</feature>
        <feature version="1.2.0" prerequisite="false" 
dependency="false">odl-yangtools-common</feature>
        <bundle>mvn:org.opendaylight.sxp/sxp-api/1.5.0</bundle>
        
<bundle>mvn:org.opendaylight.controller/sal-binding-config/1.6.0</bundle>
        <bundle>mvn:org.opendaylight.controller/config-api/0.7.0</bundle>
        <bundle>mvn:org.opendaylight.controller/sal-binding-api/1.6.0</bundle>
        <bundle>mvn:org.opendaylight.controller/sal-dom-config/1.6.0</bundle>
        <bundle>mvn:org.opendaylight.controller/sal-core-api/1.6.0</bundle>
        <bundle>mvn:org.opendaylight.mdsal/mdsal-dom-api/2.3.0</bundle>
        <bundle>mvn:org.opendaylight.controller/sal-core-spi/1.6.0</bundle>
        <bundle>mvn:org.opendaylight.mdsal/mdsal-dom-spi/2.3.0</bundle>
        
<bundle>mvn:org.opendaylight.mdsal/mdsal-singleton-dom-impl/2.3.0</bundle>
        <bundle>mvn:org.opendaylight.mdsal/mdsal-common-api/2.3.0</bundle>
        <bundle>mvn:org.opendaylight.mdsal/mdsal-eos-dom-api/2.3.0</bundle>
        <bundle>mvn:org.opendaylight.mdsal/mdsal-eos-common-api/2.3.0</bundle>
        
<bundle>mvn:org.opendaylight.mdsal/mdsal-singleton-common-api/2.3.0</bundle>
        
<bundle>mvn:org.opendaylight.controller/sal-binding-broker-impl/1.6.0</bundle>
        <bundle>mvn:org.javassist/javassist/3.20.0-GA</bundle>
        <bundle>mvn:org.opendaylight.controller/sal-binding-util/1.6.0</bundle>
        <bundle>mvn:org.opendaylight.controller/sal-broker-impl/1.6.0</bundle>
        <bundle>mvn:com.lmax/disruptor/3.3.6</bundle>
        <bundle>mvn:org.opendaylight.mdsal/mdsal-dom-broker/2.3.0</bundle>
        
<bundle>mvn:org.opendaylight.mdsal/mdsal-dom-inmemory-datastore/2.3.0</bundle>
        
<bundle>mvn:org.opendaylight.controller/sal-inmemory-datastore/1.6.0</bundle>
        <bundle>mvn:org.opendaylight.controller/sal-common-impl/1.6.0</bundle>
        
<bundle>mvn:org.opendaylight.mdsal/mdsal-binding-generator-impl/0.11.0</bundle>
        
<bundle>mvn:org.opendaylight.mdsal/mdsal-binding-generator-util/0.11.0</bundle>
        <bundle>mvn:org.opendaylight.yangtools/yang-parser-impl/1.2.0</bundle>
        <bundle>mvn:org.opendaylight.yangtools/yang-parser-api/1.2.0</bundle>
        <bundle>mvn:org.opendaylight.yangtools/yang-data-impl/1.2.0</bundle>
        <bundle>mvn:org.antlr/antlr4-runtime/4.7</bundle>
        <bundle>mvn:org.opendaylight.yangtools/yang-model-util/1.2.0</bundle>
        
<bundle>mvn:org.opendaylight.mdsal/mdsal-binding-dom-codec/0.11.0</bundle>
        
<bundle>mvn:org.opendaylight.mdsal/mdsal-binding-generator-api/0.11.0</bundle>
        <bundle>mvn:org.apache.commons/commons-lang3/3.6</bundle>
        <bundle>mvn:org.opendaylight.controller/sal-common-util/1.6.0</bundle>
        <bundle>mvn:org.opendaylight.controller/sal-common-api/1.6.0</bundle>
        <bundle>mvn:org.opendaylight.yangtools/yang-data-api/1.2.0</bundle>
        <bundle>mvn:org.opendaylight.yangtools/yang-data-util/1.2.0</bundle>
        <bundle>mvn:org.opendaylight.yangtools/yang-model-api/1.2.0</bundle>
    </feature>
</features>
{quote}

and

{quote}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<features xmlns="http://karaf.apache.org/xmlns/features/v1.4.0"; 
name="odl-yangtools-yang-parser">
    
<repository>mvn:org.opendaylight.yangtools/odl-yangtools-common/1.2.0/xml/features</repository>
    <feature name="odl-yangtools-yang-parser" description="OpenDaylight :: 
Yangtools :: YANG Parser" version="1.2.0">
        <details>OpenDaylight is leading the transformation to Open Software 
Defined Networking (SDN). For more information, please see 
https://www.opendaylight.org</details>
        <feature version="1.2.0" prerequisite="false" 
dependency="false">odl-yangtools-common</feature>
        <feature prerequisite="true" dependency="false">wrap</feature>
        <bundle>mvn:org.opendaylight.yangtools/yang-parser-impl/1.2.0</bundle>
        <bundle>mvn:org.opendaylight.yangtools/yang-model-api/1.2.0</bundle>
        <bundle>mvn:org.opendaylight.yangtools/yang-parser-api/1.2.0</bundle>
        <bundle>mvn:org.opendaylight.yangtools/yang-model-util/1.2.0</bundle>
        <bundle>mvn:org.opendaylight.yangtools/yang-data-util/1.2.0</bundle>
        <bundle>mvn:org.opendaylight.yangtools/yang-data-api/1.2.0</bundle>
        <bundle>mvn:org.antlr/antlr4-runtime/4.7</bundle>
    </feature>
</features>
{quote}

Note how they overlap in what they install, for example yang-data-api. If I try 
to feature:install these two at the same time, yang-data-api's requirements 
will be added to the resolver twice, as will be its capabilities -- which means 
the resolver will treat the same bundle (and it is the same, as things like 
dependency etc. are exactly the same) as two separate bundles.

The effect is two-fold:
# yang-data-api's requirements will be evaluated twice, which is not that big 
of a deal, as it 'just' causes the OpenHashMapList to be larger
# yang-data-api's capabilities will be subject to SUBSTITUTE permutation, which 
is costly, as the OpenHashMapList will be deep-copied

This gets worse with the number of duplicates and it also depends on complexity 
of bundle imports/exports -- and OpenDaylight uses auto-generated code, which 
has a large number of exported packages (15+ being quite common).

I can provide a heap dump (71MB compressed) that shows the layout and was used 
for the PRs I produced over the last week or so.


> ResourceImpl/RequirementImpl/CapabilityImpl do not correctly implement their 
> OSGi interface contracts
> -----------------------------------------------------------------------------------------------------
>
>                 Key: KARAF-5395
>                 URL: https://issues.apache.org/jira/browse/KARAF-5395
>             Project: Karaf
>          Issue Type: Bug
>          Components: karaf-feature
>    Affects Versions: 4.2.0, 4.1.2, 4.0.10
>            Reporter: Robert Varga
>            Assignee: Guillaume Nodet
>            Priority: Critical
>
> This is a follow-up of downstream issue tracked at 
> https://bugs.opendaylight.org/show_bug.cgi?id=9218.
> OpenDaylight uses auto-generated features, which may end up packaging a 
> bundle multiple times in separate features -- which can be regarded as a bug, 
> but it certainly is counter-intuitive.
> Using a simple test case of wanting to install all features at the same time 
> triggers huge memory usage spike in Felix Resolver.
> Since ResourceImpl does not explictly override hashCode()/equals() according 
> to org.osgi.resource.Resource interface contract, every resource declaration 
> in a feature is treated as unique -- disregarding the fact that multiple 
> bundle declarations are actually pointing to the same bundle.
> This cascades to both RequirementImpl and CapabilityImpl, hence each such 
> duplicate bundle is added to the set of Requirements to be resolved and its 
> capabilities are added to potential candidates -- leading to Felix Resolver 
> having a large problem space (what to resolve) and also having a large 
> solution space (how to resolve) -- leading to polynomial explosion in CPU and 
> memory requirements.
> The amount of memory consumed by OpenDaylight Nitrogen RC3 has been observed 
> at 1.2GB, e.g. with a heap smaller than that, the container runs into OOM 
> during feature:install before actual installation starts.



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)

Reply via email to