aboutsummaryrefslogtreecommitdiffstats
path: root/weaver
diff options
context:
space:
mode:
authorStefan Starke <stefan@starkeweb.org>2019-10-08 13:27:41 +0200
committerAndy Clement <aclement@pivotal.io>2022-01-13 15:07:30 -0800
commit0e58847d8d341b70734576aa813f755d9a716a18 (patch)
tree393edd496668ea365780412d10b40e94ee7ac963 /weaver
parent1b3cead1715cd4f233d81c88ba7a33dc1aa59886 (diff)
downloadaspectj-0e58847d8d341b70734576aa813f755d9a716a18.tar.gz
aspectj-0e58847d8d341b70734576aa813f755d9a716a18.zip
Optimize class loading
In our project we found out that during the build up of the spring context the class loading takes a very long time. Root cause is the huge amount of file I/O during pointcut class loading. We are taking about ~250k file loads. With these changes we managed to cut down the starting time by around 50%. What we found out is that IMHO - the clear method of the ClassLoaderRepository is called far too often -> in our settings this resulted in not a single cache hit as the cache got cleared permanently. Therefore we de-actived the cache clear calls inside the ClassLoaderRepository. Secondly we changed the Java15AnnotationFinder in a way to not always create new objects for the ClassLoaderRepository but re-use one static instance. Otherwise we experienced >100k objects being created. Last but not least we introduced a cache for unavailable classes so that they do not have to be looked up using file I/O over and over again. The whole behavior is configurable via + org.aspectj.apache.bcel.useSingleRepositoryInstance (default: true) + org.aspectj.apache.bcel.useUnavailableClassesCache (default: true) + org.aspectj.apache.bcel.ignoreCacheClearRequests (default: true) Signed-off-by: Stefan Starke <stefan@starkeweb.org> Signed-off-by: Alexander Kriegisch <Alexander@Kriegisch.name>
Diffstat (limited to 'weaver')
-rw-r--r--weaver/src/main/java/org/aspectj/weaver/reflect/Java15AnnotationFinder.java53
1 files changed, 39 insertions, 14 deletions
diff --git a/weaver/src/main/java/org/aspectj/weaver/reflect/Java15AnnotationFinder.java b/weaver/src/main/java/org/aspectj/weaver/reflect/Java15AnnotationFinder.java
index dfddd18da..ef437b724 100644
--- a/weaver/src/main/java/org/aspectj/weaver/reflect/Java15AnnotationFinder.java
+++ b/weaver/src/main/java/org/aspectj/weaver/reflect/Java15AnnotationFinder.java
@@ -42,9 +42,17 @@ public class Java15AnnotationFinder implements AnnotationFinder, ArgNameFinder {
private Repository bcelRepository;
private BcelWeakClassLoaderReference classLoaderRef;
+
+ private static Repository staticBcelRepository;
+ private static BcelWeakClassLoaderReference staticClassLoaderRef;
+
private World world;
private static boolean useCachingClassLoaderRepository;
+ //Use single instance of Repository and ClassLoader
+ public static final boolean useSingleInstances =
+ System.getProperty("org.aspectj.apache.bcel.useSingleRepositoryInstance", "true").equalsIgnoreCase("true");
+
static {
try {
useCachingClassLoaderRepository = System.getProperty("Xset:bcelRepositoryCaching","true").equalsIgnoreCase("true");
@@ -58,14 +66,31 @@ public class Java15AnnotationFinder implements AnnotationFinder, ArgNameFinder {
}
public void setClassLoader(ClassLoader aLoader) {
- this.classLoaderRef = new BcelWeakClassLoaderReference(aLoader);
+ //Set class loader ref
+ if (useSingleInstances && staticClassLoaderRef == null)
+ staticClassLoaderRef = new BcelWeakClassLoaderReference(aLoader);
+ else
+ this.classLoaderRef = new BcelWeakClassLoaderReference(aLoader);
+
+ //Set repository
if (useCachingClassLoaderRepository) {
- this.bcelRepository = new ClassLoaderRepository(classLoaderRef);
- } else {
- this.bcelRepository = new NonCachingClassLoaderRepository(classLoaderRef);
+ if (useSingleInstances && staticBcelRepository == null)
+ staticBcelRepository = new ClassLoaderRepository(getClassLoader());
+ else
+ this.bcelRepository = new ClassLoaderRepository(getClassLoader());
+ }
+ else {
+ if (useSingleInstances && staticBcelRepository == null)
+ staticBcelRepository = new NonCachingClassLoaderRepository(getClassLoader());
+ else
+ this.bcelRepository = new NonCachingClassLoaderRepository(getClassLoader());
}
}
+ private Repository getBcelRepository() {
+ return useSingleInstances ? staticBcelRepository : bcelRepository;
+ }
+
public void setWorld(World aWorld) {
this.world = aWorld;
}
@@ -112,7 +137,7 @@ public class Java15AnnotationFinder implements AnnotationFinder, ArgNameFinder {
}
private ClassLoader getClassLoader() {
- return classLoaderRef.getClassLoader();
+ return useSingleInstances ? staticClassLoaderRef.getClassLoader() : classLoaderRef.getClassLoader();
}
public AnnotationAJ getAnnotationOfType(UnresolvedType ofType, Member onMember) {
@@ -145,7 +170,7 @@ public class Java15AnnotationFinder implements AnnotationFinder, ArgNameFinder {
anns = bcelField.getAnnotations();
}
// the answer is cached and we don't want to hold on to memory
- bcelRepository.clear();
+ getBcelRepository().clear();
// OPTIMIZE make constant 0 size array for sharing
if (anns == null)
anns = AnnotationGen.NO_ANNOTATIONS;
@@ -164,7 +189,7 @@ public class Java15AnnotationFinder implements AnnotationFinder, ArgNameFinder {
public String getAnnotationDefaultValue(Member onMember) {
try {
- JavaClass jc = bcelRepository.loadClass(onMember.getDeclaringClass());
+ JavaClass jc = getBcelRepository().loadClass(onMember.getDeclaringClass());
if (onMember instanceof Method) {
org.aspectj.apache.bcel.classfile.Method bcelMethod = jc.getMethod((Method) onMember);
@@ -200,7 +225,7 @@ public class Java15AnnotationFinder implements AnnotationFinder, ArgNameFinder {
// we can just use reflection.
if (!areRuntimeAnnotationsSufficient) {
try {
- JavaClass jc = bcelRepository.loadClass(onMember.getDeclaringClass());
+ JavaClass jc = getBcelRepository().loadClass(onMember.getDeclaringClass());
org.aspectj.apache.bcel.classfile.annotation.AnnotationGen[] anns = null;
if (onMember instanceof Method) {
org.aspectj.apache.bcel.classfile.Method bcelMethod = jc.getMethod((Method) onMember);
@@ -215,7 +240,7 @@ public class Java15AnnotationFinder implements AnnotationFinder, ArgNameFinder {
anns = bcelField.getAnnotations();
}
// the answer is cached and we don't want to hold on to memory
- bcelRepository.clear();
+ getBcelRepository().clear();
if (anns == null || anns.length == 0) {
return ResolvedType.NONE;
}
@@ -246,9 +271,9 @@ public class Java15AnnotationFinder implements AnnotationFinder, ArgNameFinder {
// annotations so we bail out to Bcel and then chuck away the JavaClass so that we
// don't hog memory.
try {
- JavaClass jc = bcelRepository.loadClass(forClass);
+ JavaClass jc = getBcelRepository().loadClass(forClass);
org.aspectj.apache.bcel.classfile.annotation.AnnotationGen[] anns = jc.getAnnotations();
- bcelRepository.clear();
+ getBcelRepository().clear();
if (anns == null) {
return ResolvedType.NONE;
} else {
@@ -276,7 +301,7 @@ public class Java15AnnotationFinder implements AnnotationFinder, ArgNameFinder {
return null;
try {
- JavaClass jc = bcelRepository.loadClass(forMember.getDeclaringClass());
+ JavaClass jc = getBcelRepository().loadClass(forMember.getDeclaringClass());
LocalVariableTable lvt = null;
int numVars = 0;
if (forMember instanceof Method) {
@@ -320,7 +345,7 @@ public class Java15AnnotationFinder implements AnnotationFinder, ArgNameFinder {
// don't hog
// memory.
try {
- JavaClass jc = bcelRepository.loadClass(onMember.getDeclaringClass());
+ JavaClass jc = getBcelRepository().loadClass(onMember.getDeclaringClass());
org.aspectj.apache.bcel.classfile.annotation.AnnotationGen[][] anns = null;
if (onMember instanceof Method) {
org.aspectj.apache.bcel.classfile.Method bcelMethod = jc.getMethod((Method) onMember);
@@ -340,7 +365,7 @@ public class Java15AnnotationFinder implements AnnotationFinder, ArgNameFinder {
// anns = null;
}
// the answer is cached and we don't want to hold on to memory
- bcelRepository.clear();
+ getBcelRepository().clear();
if (anns == null)
return NO_PARAMETER_ANNOTATIONS;
ResolvedType[][] result = new ResolvedType[anns.length][];