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

Thomas Watson commented on FELIX-5247:
--------------------------------------

The ResolverImpl can be constructed with an optional Executor that can control 
the lifecycle of the threads used.  In the Equinox framework I use this 
constructor so I can have my own executor that manages the pool of threads.  
Equinox also registers the Resolver service with a ResolverImpl that uses a 
synchronous (single threaded) executor.  That effectively makes the Resolver 
service single threaded.

I'm still not convinced the work the resolver does in parallel is buy us much 
in terms of resolver speed, even if you remove the noise of creating and 
destroying 100s of threads.

> Reduce number of threads created by Resolver during a startup of OSGi-based 
> applications
> ----------------------------------------------------------------------------------------
>
>                 Key: FELIX-5247
>                 URL: https://issues.apache.org/jira/browse/FELIX-5247
>             Project: Felix
>          Issue Type: Improvement
>          Components: Framework, Resolver
>    Affects Versions: framework-5.4.0, resolver-1.8.0
>            Reporter: Dmitry Konstantinov
>              Labels: performance
>         Attachments: karaf_thread_creation.png
>
>
> Thread creation is a quite expensive operation, so it make sense to reuse 
> threads in ResolverImpl if they are needed to split some task and do it in 
> parallel.
> For example: Apache Karaf startup with several features can install about 300 
> bundles. If each one will create Runtime.getRuntime().availableProcessors() 
> threads - so, during a startup about 1000 threads will be created only by 
> Resolver (in case of a server machine even much more). Thread creation takes 
> let's say (depends on machine, JDK, OS, etc) about 10-20 ms, so we are 
> spending about 1-2 seconds of startup time only to create some threads.
> it make sense to create a thread pool once (with a configurable thread 
> number) and reuse it for resolving of different bundles.
> Threads creation, stack examples:
> {noformat}
> java.lang.Thread.<init>(ThreadGroup, Runnable, String, long) Thread.java
> java.util.concurrent.Executors$DefaultThreadFactory.newThread(Runnable) 
> Executors.java:613
> java.util.concurrent.ThreadPoolExecutor$Worker.<init>(ThreadPoolExecutor, 
> Runnable) ThreadPoolExecutor.java:612
> java.util.concurrent.ThreadPoolExecutor.addWorker(Runnable, boolean) 
> ThreadPoolExecutor.java:925
> java.util.concurrent.ThreadPoolExecutor.execute(Runnable) 
> ThreadPoolExecutor.java:1357
> org.apache.felix.resolver.ResolverImpl$EnhancedExecutor.execute(Runnable) 
> ResolverImpl.java:2436
> org.apache.felix.resolver.ResolverImpl$1Computer.run() ResolverImpl.java:1150
> org.apache.felix.resolver.ResolverImpl$EnhancedExecutor$1.run() 
> ResolverImpl.java:2442
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor$Worker) 
> ThreadPoolExecutor.java:1142
> java.util.concurrent.ThreadPoolExecutor$Worker.run() 
> ThreadPoolExecutor.java:617
> java.lang.Thread.run() Thread.java:745
> {noformat}
> {noformat}
> java.lang.Thread.<init>(ThreadGroup, Runnable, String, long) Thread.java
> java.util.concurrent.Executors$DefaultThreadFactory.newThread(Runnable) 
> Executors.java:613
> java.util.concurrent.ThreadPoolExecutor$Worker.<init>(ThreadPoolExecutor, 
> Runnable) ThreadPoolExecutor.java:612
> java.util.concurrent.ThreadPoolExecutor.addWorker(Runnable, boolean) 
> ThreadPoolExecutor.java:925
> java.util.concurrent.ThreadPoolExecutor.execute(Runnable) 
> ThreadPoolExecutor.java:1357
> org.apache.felix.resolver.ResolverImpl$EnhancedExecutor.execute(Runnable) 
> ResolverImpl.java:2436
> org.apache.felix.resolver.ResolverImpl.calculatePackageSpaces(Executor, 
> ResolverImpl$ResolveSession, Candidates, Collection) ResolverImpl.java:1158
> org.apache.felix.resolver.ResolverImpl.checkConsistency(Executor, 
> ResolverImpl$ResolveSession, List, List, Candidates, Map, Map, boolean) 
> ResolverImpl.java:471
> org.apache.felix.resolver.ResolverImpl.resolve(ResolveContext, Executor) 
> ResolverImpl.java:347
> org.apache.felix.resolver.ResolverImpl.resolve(ResolveContext) 
> ResolverImpl.java:158
> org.apache.felix.framework.StatefulResolver.resolve(Set, Set) 
> StatefulResolver.java:431
> org.apache.felix.framework.Felix.resolveBundleRevision(BundleRevision) 
> Felix.java:4118
> org.apache.felix.framework.Felix.startBundle(BundleImpl, int) Felix.java:2124
> org.apache.felix.framework.BundleImpl.start(int) BundleImpl.java:998
> org.apache.felix.framework.BundleImpl.start() BundleImpl.java:984
> org.apache.karaf.features.internal.FeaturesServiceImpl.startBundle(InstallationState,
>  Bundle) FeaturesServiceImpl.java:520
> org.apache.karaf.features.internal.FeaturesServiceImpl.installFeatures(Set, 
> EnumSet) FeaturesServiceImpl.java:478
> org.apache.karaf.features.internal.FeaturesServiceImpl.installFeature(Feature,
>  EnumSet) FeaturesServiceImpl.java:419
> org.apache.karaf.features.internal.FeaturesServiceImpl.installFeature(String, 
> String, EnumSet) FeaturesServiceImpl.java:394
> org.apache.karaf.features.internal.FeaturesServiceImpl.installFeature(String, 
> EnumSet) FeaturesServiceImpl.java:364
> {noformat}



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to