Caching for Bug 318817 - Too many memory allocations in the background (without user activity)
diff --git a/bundles/org.eclipse.e4.core.di/src/org/eclipse/e4/core/internal/di/InjectorImpl.java b/bundles/org.eclipse.e4.core.di/src/org/eclipse/e4/core/internal/di/InjectorImpl.java
index 7d8c5f0..07528cc 100644
--- a/bundles/org.eclipse.e4.core.di/src/org/eclipse/e4/core/internal/di/InjectorImpl.java
+++ b/bundles/org.eclipse.e4.core.di/src/org/eclipse/e4/core/internal/di/InjectorImpl.java
@@ -27,6 +27,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.WeakHashMap;
 import javax.annotation.PostConstruct;
 import javax.annotation.PreDestroy;
 import javax.inject.Inject;
@@ -54,6 +55,7 @@
 	private Set<WeakReference<Class<?>>> injectedClasses = new HashSet<WeakReference<Class<?>>>();
 	private HashMap<Class<?>, Object> singletonCache = new HashMap<Class<?>, Object>();
 	private Map<Class<?>, Set<Binding>> bindings = new HashMap<Class<?>, Set<Binding>>();
+	private Map<Class<?>, Method[]> methodsCache = new WeakHashMap<Class<?>, Method[]>();
 
 	public void inject(Object object, PrimaryObjectSupplier objectSupplier) {
 		inject(object, objectSupplier, null);
@@ -175,7 +177,7 @@
 	}
 
 	private Object invokeUsingClass(Object userObject, Class<?> currentClass, Class<? extends Annotation> qualifier, Object defaultValue, PrimaryObjectSupplier objectSupplier, PrimaryObjectSupplier tempSupplier, boolean throwUnresolved) {
-		Method[] methods = currentClass.getDeclaredMethods();
+		Method[] methods = getDeclaredMethods(currentClass);
 		for (int j = 0; j < methods.length; j++) {
 			Method method = methods[j];
 			if (method.getAnnotation(qualifier) == null)
@@ -576,7 +578,7 @@
 	 */
 	private boolean processMethods(final Object userObject, PrimaryObjectSupplier objectSupplier, PrimaryObjectSupplier tempSupplier, Class<?> objectsClass, ArrayList<Class<?>> classHierarchy, boolean track, List<Requestor> requestors) {
 		boolean injectedStatic = false;
-		Method[] methods = objectsClass.getDeclaredMethods();
+		Method[] methods = getDeclaredMethods(objectsClass);
 		for (int i = 0; i < methods.length; i++) {
 			final Method method = methods[i];
 			if (isOverridden(method, classHierarchy))
@@ -629,6 +631,15 @@
 		return false;
 	}
 
+	private Method[] getDeclaredMethods(Class<?> c) {
+		Method[] methods = methodsCache.get(c);
+		if (methods == null) {
+			methods = c.getDeclaredMethods();
+			methodsCache.put(c, methods);
+		}
+		return methods;
+	}
+
 	private Class<?> getDesiredClass(Type desiredType) {
 		if (desiredType instanceof Class<?>)
 			return (Class<?>) desiredType;
@@ -734,7 +745,7 @@
 			processAnnotated(annotation, userObject, superClass, objectSupplier, tempSupplier, classHierarchy);
 			classHierarchy.remove(objectClass);
 		}
-		Method[] methods = objectClass.getDeclaredMethods();
+		Method[] methods = getDeclaredMethods(objectClass);
 		for (int i = 0; i < methods.length; i++) {
 			Method method = methods[i];
 			if (!method.isAnnotationPresent(annotation))