Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] LTW (load time weaving) with Aj throws OutOfMemoryError


> My Ant task will destroy the classloader which creates Aj after each processing. It looks to me the
> loaded/transformed classes is not clean up when the classloader is destroyed.
> I used the latest AspectJ relase, 1.6.1

I specifically tested that tidy up is occurring with 1.6.1 and all my scenarios confirm it - however that is doing loadtime weaving the regular way.  I have seen problems with Ant where classloaders have not been released, even when you think they must have.  Can you run your classloader in a regular Java scenario outside of Ant and confirm whether it behaves?

There is an API call

org.aspectj.weaver.loadtime.Aj.removeStaleAdaptors(true)

that will attempt to remove weavers attached to stale classloaders.  Try calling that and seeing what output you get - if they cannot be tidied up then the classloaders have not been orphaned.  In that case collect some hprof profiling output and use something like (j)hat to see who is holding on to references to them.  If it is the weaver then I have a bug to fix.

What is still a problem is that over time the weaver instances will get larger and larger and never shrink - we have an open bug report for that.  But if you are constantly using different classloaders (and so different weaver instances) then they will come and go and never grow out of control.

Andy.


2008/7/22 Anfernee Xu <anfernee.xu@xxxxxxxxx>:
Hi,

I'm developing an Ant task which will use LTW to enhance the classes specified in <classpath> nested element of my Ant task. Basically, I create a subclass of AntClassLoader, the classloader is at the bottom of classloader tree. and use org.aspectj.weaver.loadtime.Aj to perform LTW,
here's my ClassLoader code snippet,

class WeaveClassLoader extends AntClassLoader {

  // aspectj byte-code transformer
  protected Aj transformer = null;

  // whether need byte-code transformer.
  protected boolean isAjOn = false;

@Override
 protected final Class defineClassFromData(File container, byte[] classData,
      String classname) throws IOException {

    byte[] classBytes = transform(classname, classData, this);
    return super.defineClassFromData(container, classBytes, classname);

  }

protected byte[] transform(String classname, byte[] byteCode,
      ClassLoader classloader) {
    if (isTransformerTurnOn() && isWeavedClass(classname))
      return transformer.preProcess(classname, byteCode, this);
    return byteCode;
  }


  @Override
  protected synchronized Class loadClass(String classname, boolean resolve)
      throws ClassNotFoundException {
    Class theClass = findLoadedClass(classname);
    if (theClass != null) {
      return theClass;
    }
    if (isSplit(classname) || isAspect(classname)) {
      theClass = findClass(classname);
      if (resolve) {
        resolveClass(theClass);
      }

    } else {
      theClass = super.loadClass(classname, resolve);
    }

    return theClass;
  }

The function run pretty well, but over time, it consumed more memory and eventually threw OutOfMemory and aborted.

The stacktrace is as follows,

testErrorHandling_exceptiontype:
 Jul 20, 2008 2:36:10 PM org.aspectj.weaver.tools.Jdk14Trace error
 SEVERE: junit.framework.Test
 java.lang.OutOfMemoryError: CG(q0) [org/aspectj/apache/bcel/Constants.<clinit>()V] JVM@cgFail (src/jvm/code/codemanager.c:693). Java heapsize=604577792, pa
     at org.aspectj.apache.bcel.classfile.Attribute.readAttribute(Attribute.java:177)
     at org.aspectj.apache.bcel.classfile.FieldOrMethod.<init>(FieldOrMethod.java:111)
     at org.aspectj.apache.bcel.classfile.Field.<init>(Field.java:83)
     at org.aspectj.apache.bcel.classfile.ClassParser.readFields(ClassParser.java:280)
     at org.aspectj.apache.bcel.classfile.ClassParser.parse(ClassParser.java:172)
     at org.aspectj.apache.bcel.util.ClassLoaderRepository.loadClass(ClassLoaderRepository.java:288)
     at org.aspectj.weaver.bcel.BcelWorld.lookupJavaClass(BcelWorld.java:369)
     at org.aspectj.weaver.bcel.BcelWorld.resolveDelegate(BcelWorld.java:338)
     at org.aspectj.weaver.ltw.LTWWorld.resolveDelegate(LTWWorld.java:97)
     at org.aspectj.weaver.World.resolveToReferenceType(World.java:378)
     at org.aspectj.weaver.World.resolve(World.java:271)
     at org.aspectj.weaver.bcel.BcelWeaver.addLibraryAspect(BcelWeaver.java:165)
     at org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor.registerAspects(ClassLoaderWeavingAdaptor.java:399)
     at org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor.registerDefinitions(ClassLoaderWeavingAdaptor.java:240)
     at org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor.initialize(ClassLoaderWeavingAdaptor.java:152)
     at org.aspectj.weaver.loadtime.Aj$ExplicitlyInitializedClassLoaderWeavingAdaptor.initialize(Aj.java:151)
     at org.aspectj.weaver.loadtime.Aj$ExplicitlyInitializedClassLoaderWeavingAdaptor.getWeavingAdaptor(Aj.java:156)
     at org.aspectj.weaver.loadtime.Aj$WeaverContainer.getWeaver(Aj.java:122)
     at org.aspectj.weaver.loadtime.Aj.preProcess(Aj.java:73)
.....
 Jul 20, 2008 2:36:10 PM org.aspectj.weaver.tools.Jdk14Trace info
 INFO: Dumping to .\ajcore.20080720.143610.453.txt
   302  tests.functional.webapp.servlet25.clarifications.client.TestClarifications.testClarifications (junit)
 testErrorHandling_errorcode:
 Jul 20, 2008 2:36:12 PM org.aspectj.weaver.tools.Jdk14Trace error
 SEVERE: junit.framework.Test
 java.lang.OutOfMemoryError: class allocation, 967086156 loaded, 893648896 footprint JVM@check_alloc (src/jvm/model/classload/classalloc.c:118). 5841 bytes
     at java.lang.ClassLoader.defineClass1(Native Method)
     at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
     at org.apache.tools.ant.loader.AntClassLoader2.defineClassFromData(AntClassLoader2.java:78)
     at org.apache.tools.ant.AntClassLoader.getClassFromStream(AntClassLoader.java:1090)
     at org.apache.tools.ant.AntClassLoader.findClassInComponents(AntClassLoader.java:1154)
     at org.apache.tools.ant.AntClassLoader.loadClass(AntClassLoader.java:984)
     at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
     at org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor.initialize(ClassLoaderWeavingAdaptor.java:140)
     at org.aspectj.weaver.loadtime.Aj$ExplicitlyInitializedClassLoaderWeavingAdaptor.initialize(Aj.java:151)
     at org.aspectj.weaver.loadtime.Aj$ExplicitlyInitializedClassLoaderWeavingAdaptor.getWeavingAdaptor(Aj.java:157)
     at org.aspectj.weaver.loadtime.Aj$WeaverContainer.getWeaver(Aj.java:122)
     at org.aspectj.weaver.loadtime.Aj.preProcess(Aj.java:73)



My Ant task will destroy the classloader which creates Aj after each processing. It looks to me the loaded/transformed classes is not clean up when the classloader is destroyed.
I used the latest AspectJ relase, 1.6.1

Any help is appreciated.

Anfernee

_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/aspectj-users



Back to the top