Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthieu Helleboid2015-01-15 09:48:58 +0000
committerThomas Watson2015-01-16 13:42:25 +0000
commit16bb483bd75d665c3ff6a554419ddf8ad93bab57 (patch)
tree94942f3a240494d11961fe332aec1cb4d89af2ed /bundles
parente7db81bab4bce237fcafd3d624e56d183bbd6dae (diff)
downloadrt.equinox.framework-16bb483bd75d665c3ff6a554419ddf8ad93bab57.tar.gz
rt.equinox.framework-16bb483bd75d665c3ff6a554419ddf8ad93bab57.tar.xz
rt.equinox.framework-16bb483bd75d665c3ff6a554419ddf8ad93bab57.zip
Bug 457118 - OutOfMemoryError (Java Heap Space) when resolving bundles
Resolve bundles in batch for performance reason related to https://bugs.eclipse.org/bugs/show_bug.cgi?id=421706 Bug: 457118 Change-Id: I39f738e3570c1c43d59487e346393ecc98df6305 Signed-off-by: Matthieu Helleboid <matthieu.helleboid@thalesgroup.com>
Diffstat (limited to 'bundles')
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleResolver.java59
1 files changed, 38 insertions, 21 deletions
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleResolver.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleResolver.java
index 4269eca72..0f980da00 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleResolver.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleResolver.java
@@ -451,6 +451,8 @@ final class ModuleResolver {
}
class ResolveProcess extends ResolveContext implements Comparator<Capability>, FelixResolveContext {
+ private static final int RESOLVE_REVISIONS_BATCH_SIZE = 100;
+
class ResolveLogger extends Logger {
private Map<Resource, ResolutionException> errors = null;
@@ -501,7 +503,7 @@ final class ModuleResolver {
*/
private final Collection<ModuleRevision> disabled;
private final Collection<ModuleRevision> triggers;
- private final Collection<ModuleRevision> optionals;
+ private final List<ModuleRevision> optionals;
private final boolean triggersMandatory;
private final ModuleDatabase moduleDatabase;
private final Map<ModuleRevision, ModuleWiring> wirings;
@@ -509,7 +511,7 @@ final class ModuleResolver {
private final DynamicModuleRequirement dynamicReq;
private volatile ResolverHook hook = null;
private volatile Map<String, Collection<ModuleRevision>> byName = null;
- private volatile ModuleRevision currentlyResolving = null;
+ private volatile List<Resource> currentlyResolving = null;
private volatile boolean currentlyResolvingMandatory = false;
private final Set<Resource> transitivelyResolveFailures = new LinkedHashSet<Resource>();
private final Set<Resource> failedToResolve = new HashSet<Resource>();
@@ -783,7 +785,7 @@ final class ModuleResolver {
@Override
public Collection<Resource> getMandatoryResources() {
if (currentlyResolvingMandatory) {
- return Collections.<Resource> singleton(currentlyResolving);
+ return Collections.unmodifiableList(currentlyResolving);
}
return Collections.emptyList();
}
@@ -791,7 +793,7 @@ final class ModuleResolver {
@Override
public Collection<Resource> getOptionalResources() {
if (!currentlyResolvingMandatory) {
- return Collections.<Resource> singleton(currentlyResolving);
+ return Collections.unmodifiableList(currentlyResolving);
}
return Collections.emptyList();
}
@@ -870,13 +872,10 @@ final class ModuleResolver {
result.putAll(dynamicAttachWirings);
}
if (triggersMandatory) {
- for (ModuleRevision mandatory : triggers) {
- resolveSingleRevision(mandatory, true, logger, result);
- }
- }
- for (ModuleRevision optional : optionals) {
- resolveSingleRevision(optional, false, logger, result);
+ resolveRevisionsInBatch(triggers, true, logger, result);
}
+
+ resolveRevisionsInBatch(optionals, false, logger, result);
}
} catch (ResolutionException e) {
re = e;
@@ -930,21 +929,42 @@ final class ModuleResolver {
Debug.println(builder);
}
- private void resolveSingleRevision(ModuleRevision single, boolean isMandatory, ResolveLogger logger, Map<Resource, List<Wire>> result) throws ResolutionException {
- if (wirings.containsKey(single) || failedToResolve.contains(single)) {
- return;
+ private void resolveRevisionsInBatch(Collection<ModuleRevision> revisions, boolean isMandatory, ResolveLogger logger, Map<Resource, List<Wire>> result) throws ResolutionException {
+ long startTime = System.currentTimeMillis();
+ long initialFreeMemory = Runtime.getRuntime().freeMemory();
+ long maxUsedMemory = 0;
+
+ List<Resource> toResolve = new ArrayList<Resource>();
+ while (revisions.size() > 0) {
+ Resource single = revisions.iterator().next();
+ revisions.remove(single);
+ if (DEBUG_ROOTS) {
+ Debug.println("Resolver: Resolving root bundle: " + single); //$NON-NLS-1$
+ }
+ if (!wirings.containsKey(single) && !failedToResolve.contains(single)) {
+ toResolve.add(single);
+ }
+ if (toResolve.size() == RESOLVE_REVISIONS_BATCH_SIZE || revisions.size() == 0) {
+ resolveRevisions(toResolve, isMandatory, logger, result);
+ toResolve.clear();
+ }
+ maxUsedMemory = Math.max(maxUsedMemory, Runtime.getRuntime().freeMemory() - initialFreeMemory);
}
- long startTime = 0;
+
if (DEBUG_ROOTS) {
- startTime = System.currentTimeMillis();
- Debug.print("Resolver: Resolving root bundle: " + single); //$NON-NLS-1$
+ Debug.println("Resolver: resolve batch size: " + RESOLVE_REVISIONS_BATCH_SIZE); //$NON-NLS-1$ //$NON-NLS-2$
+ Debug.println("Resolver: time to resolve: " + (System.currentTimeMillis() - startTime) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
+ Debug.println("Resolver: max used memory: " + maxUsedMemory / (1024 * 1024) + "Mo"); //$NON-NLS-1$ //$NON-NLS-2$
}
- currentlyResolving = single;
+ }
+
+ private void resolveRevisions(List<Resource> revisions, boolean isMandatory, ResolveLogger logger, Map<Resource, List<Wire>> result) throws ResolutionException {
+ currentlyResolving = revisions;
currentlyResolvingMandatory = isMandatory;
transitivelyResolveFailures.clear();
Map<Resource, List<Wire>> interimResults = null;
try {
- transitivelyResolveFailures.add(single);
+ transitivelyResolveFailures.addAll(revisions);
interimResults = new ResolverImpl(logger).resolve(this);
applyInterimResultToWiringCopy(interimResults);
// now apply the simple wires to the results
@@ -966,9 +986,6 @@ final class ModuleResolver {
currentlyResolving = null;
currentlyResolvingMandatory = false;
}
- if (DEBUG_ROOTS) {
- Debug.println(" [" + (System.currentTimeMillis() - startTime) + "ms]"); //$NON-NLS-1$ //$NON-NLS-2$
- }
}
private void applyInterimResultToWiringCopy(Map<Resource, List<Wire>> interimResult) {

Back to the top