Project: AspectJ
Bug 122347 Contribution: Memory Efficient Expendable Type Map
Reported: 2005-12-29 18:49:19 | Status: resolved wontfix

Here is a patch for a single file (weaver/src/org/aspectj/weaver/World) that significantly improves the memory footprint of weaves (see details below). I would like help in resolving the one bug that this hit in the AspectJ weaver tests. It does the following: * Keeps Weak References to the values in the expendable map to allow evicting them (whereas the Weak Hash Map keeps weak references only to the keys) * Allows configuring the expendable map to keep hard references to up to N types with -Dorg.aspectj.weaver.World.cacheRetention=number (the current default is 0). It's a nice tuning option so projects can use a bit more memory to avoid evicting types. * Moves the isExpendible check from the typeMap to the world, to allow different worlds (such as the LTWWorld) to change what's evictable (this lets the LTWWorld not keep references to already defined classes) This change breaks 3 tests in the "run these tests before checking in code" suite, all of them an NPE in the same line of ReferenceType.getTypeVariables for generic signatures. Presumably this code is implicitly relying on "expendable" types never being evicted. I have attached the error output for all 3 cases. My initial tests have shown a relatively small performance loss in return for significant memory footprint gains. E.g., using the AspectJ in CVS HEAD with the standard BcelWorld implementation (not LTWWorld) as the world, in Tomcat with the Glassbox Inspector & 4 web apps the AspectJ overhead with this optimization is 48 million heap bytes (of 60 million total heap bytes) versus 61 million bytes using CVS HEAD. The optimization has limited benefit for a BcelWorld where almost all the code is exposed to the weaver (since few types are expendible). However, Martin Lippert tried a version of this in his AJEER Eclipse load-time weaving environment and reported a reduction from 230 MB of heap to 30 MB heap used at a cost of a 25% increase in start up time. Likewise, this facility is the major contributor to enabling my other LTW optimizations that can reduce the heap overhead in my test case to 9 million heap bytes (principally having the LTW world allow evicting types that are already woven and using reflective proxies). I see similar start up times when using this expendable map in my tests. The ability to increase the number of hard references in cache should provide users an ability to allocate more memory to speed up performance. Note that the only hard reference to the keys (the signatures) is from the values (at least I haven't noticed any cases in my load-time weaving tests), so the weak hash map is compacting itself properly: when the reference type is weakly reachable, the key is then weakly reachable and the map ultimately purges theses entries.

Files changed in fix:
weaver/src/org/aspectj/weaver/World.java weaver/src/org/aspectj/weaver/bcel/BcelWorld.java