[
https://issues.apache.org/jira/browse/FELIX-5247?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15548093#comment-15548093
]
Dmitry Konstantinov commented on FELIX-5247:
--------------------------------------------
Guillaume, thanks a lot for the change.
Just a small comment regarding the commit - shutdownNow does not wait for
actively executing tasks to terminate, so in the current form there is a small
probability what in some cases a task will try to work with resources which are
closing or closed and it can cause some additional errors in logs, may be it
make sense to add awaitTermination with some small timeout to Resolver stop
logic.
> 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
> Assignee: Guillaume Nodet
> Labels: performance
> Fix For: framework-5.8.0
>
> 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)