Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] Garbage collector behavior

Hi -

I'm glad you-all are working hard on the issue of memory
usage, but one (perhaps too basic) question I have is
whether the usage is greater than it would have been had
the same functionality been written in Java.  It seems to
me that the current implementation of aspects would use
less memory than a pure-java solution with scattered and
duplicated code (assuming unused class attributes are not
held in memory).  And wouldn't it be harder for the VM to
optimize the scattered code than the aspects?  

We'd always like to get better than we are, but I'd like to
avoid the misperception that we are worse than "regular"
Java.

Wes

On Tue, 1 Nov 2005 10:22:04 -0800
 "Ron Bodkin" <rbodkin@xxxxxxxxxxxxxx> wrote:
> Hi Matthew,
> 
> 1. If the reaper only accesses a single object at a time,
> it could at worst
> add a bit of contention, and never create deadlocks,
> right? One approach is
> to create a reflective proxy for the BCEL bytecode
> without locking anything
> and then swizzle the map entry at the last moment. This
> would absolutely
> minimize contention.
> 
> There might value in using AspectJ to apply appropriate
> concurrency
> strategies on a Java 1.3-, 1.4 and 1.5+ VM using best
> efforts, the
> java.util.concurrent backport, and java.util.concurrent
> respectively. For a
> 1.3- VM, I'd just synchronize on the weaver for the
> update to the map. For
> 1.4+ I'd use a concurrent hash map (maybe extending it to
> concurrent weak
> hash map).
> 
> This is an area where I plan to work on some reusable
> library aspects,
> hopefully collaborating with Ramnivas who has written
> some nice examples.
> 
> I agree we need to analyze the memory usage carefully:
> intuitively the
> memory used by aspects ought to be small, although in the
> Inspector case I'm
> seeing an extra 2 MB per classloader which translates to
> 2 MB per JSP. If as
> I believe this is caused by the redundant, sharable
> aspect bytecode, then it
> is actually a pretty big problem that would affect many
> interesting aspects
> that apply to a Web application. Re: using the aspect
> bytecode, doesn't the
> new MAP provide sufficient reflective information to
> implement this kind of
> proxy for aspects based on the bytecode definition? If
> not, do you know what
> is still lacking?
> 
> 2. I thought Alex said that weaver has to be reentrant.
> Either way, long
> term it would be highly desirable to make it so and to
> just load aspects
> (and everything) through the standard classloader
> mechanism instead of this
> complex parallel bytecode loading mechanism that is
> really suited to
> compilers and not load time environments, IMHO.
> 
> 3. Re "I think weaving into well known ClassLoaders to
> allow a
> ClassLoaderWeavingAdaptor that delegates to a parent
> would be natural too."
> I am suggesting that we build on the technique you
> suggested, whereby we
> write aspects that weave into common ClassLoaders like
> Tomcat's (especially
> the JasperLoader for JSP) to add hooks after defining
> classes. My idea is
> that we can encode knowledge of delegation into these
> aspects so we can set
> up a proper hierarchical weaving structure based on
> knowledge of whether the
> loaders are delegating or not. I think that having real
> hierarchy in the
> weavers will allow another level of efficiency beyond
> what can be achieved
> by sharing bytecodes. Of course if shared bytecodes
> 
> 4. Re: "Sounds dangerous"
> I would also say that if users explicitly configure a
> delegating/nondelegating mode for a classloader
> hierarchy, they need to know
> what they're doing. In truth Java users (developers)
> routinely have problems
> with ClassLoader resolution already. But I would far
> rather have options
> that are not a default that can be used to get acceptable
> performance in the
> near term, if the benefit is compelling.
> 
> I don't think would be redundant in the general case,
> although if we
> recognize all the popular non-delegating ClassLoaders it
> could be an obscure
> option for custom ones (or maybe we publish a marker
> interface & an
> annotation...)
> ________________________________________
> From: aspectj-users-bounces@xxxxxxxxxxx
> [mailto:aspectj-users-bounces@xxxxxxxxxxx] On Behalf Of
> Matthew Webster
> Sent: Tuesday, November 01, 2005 9:23 AM
> To: aspectj-users@xxxxxxxxxxx
> Subject: RE: [aspectj-users] Garbage collector behavior
> 
> 
> Ron, 
> 
> My only concern with a reaper thread would be the locking
> issues. I think
> making the weaver re-entrant is a great goal but probably
> non-trivial. We
> still need byte-code for aspects as we can't use Java
> reflection to obtain
> cross-cutting meta-data and it's not a such big deal as
> the number of
> aspects is small compared to the number of classes.
> However it may be
> possible to create a hybrid that initially uses byte-code
> but after the
> aspect is defined uses a Class object for Java meta-data.
> I don't think
> there is any complexity in loading byte-code because it
> is encapsulated in
> the BcelObjectType delegate and needed for binary
> weaving. 
> 
> 
> >I think weaving into well known ClassLoaders to allow a
> ClassLoaderWeavingAdaptor that delegates to a parent
> would be natural too. 
> Please explain. 
> 
> >One thought: what if we allow a delegating flag in an
> aop.xml deployment
> descriptor, which would indicate it is supporting normal
> delegation
> semantics. This would let >us fairly easily reuse weaving
> data from a parent
> classloader?s definitions? 
> Sounds dangerous. Can't trust user configuration to get
> type resolution
> correct. This may be redundant if we weave define class
> callbacks. 
> 
> Cheers 
> 
> Matthew Webster
> AOSD Project
> Java Technology Centre, MP146
> IBM Hursley Park, Winchester,  SO21 2JN, England
> Telephone: +44 196 2816139 (external) 246139 (internal) 
> Email: Matthew Webster/UK/IBM @ IBMGB,
> matthew_webster@xxxxxxxxxx 
> http://w3.hursley.ibm.com/~websterm/ 
> Please respond to aspectj-users@xxxxxxxxxxx 
> Sent by:        aspectj-users-bounces@xxxxxxxxxxx 
> To:        <aspectj-users@xxxxxxxxxxx> 
> cc:         
> Subject:        RE: [aspectj-users] Garbage collector
> behavior 
> 
> 
> I agree that only holding on to bytes that are actually
> woven would be a
> useful optimization. 
>   
> I like your idea of weaving into popular ClassLoaders
> like Tomcat?s to avoid
> using byte code for woven classes. Another technique that
> can work is to use
> accessible object to invoke ClassLoader.findLoadedClass
> to determine if a
> given class loader has loaded a class but won?t cause
> loading if it hasn?t.
> I tested using this approach to create proxies instead of
> loading bytes, but
> in this case the weaver has always defined the class in
> advance. This could
> be done on a cache ?reaper? thread that periodically
> reclaims memory. 
>   
> To share memory among aspects, it would be useful if we
> could do the same
> approach: rely on a proxy for the loaded .class
> representation of the
> aspect, rather than keeping separate copies of the bytes
> in each
> ClassLoader. What if we made the weaver set up reentrant,
> so that it just
> loaded the aspects like any other class rather than
> having this separate
> mechanism of loading bytecodes? It seems to me that the
> root of all the
> complexity is separately loading and managing these
> bytecodes. This would
> undoubtedly add complexity, since the weaver would be in
> an ?initializing?
> mode while it is looping over aspect definitions. But the
> payoff would be
> significant reuse. 
>   
> I think weaving into well known ClassLoaders to allow a
> ClassLoaderWeavingAdaptor that delegates to a parent
> would be natural too. 
>   
> I think it?s really important to avoid 1-3 MB of overhead
> per ClassLoader
> when there?s one ClassLoader per JSP. I also think this
> same need for
> lightweight weaver extension support will be important
> when reconsidering
> reweaving when there are build-time woven aspects that
> aren?t in the aop.xml
> definition file? 
>   
> 
> ________________________________________
> 
> From: aspectj-users-bounces@xxxxxxxxxxx
> [mailto:aspectj-users-bounces@xxxxxxxxxxx] On Behalf Of
> Matthew Webster
> Sent: Monday, October 31, 2005 8:24 AM
> To: aspectj-users@xxxxxxxxxxx
> Subject: RE: [aspectj-users] Garbage collector behavior 
>   
> 
> Ron, 
> 
> I suspect the 900 classes you see in
> world.delegate.loaded represent the
> whole of your Spring application: this collection holds
> all types exposed to
> the weaver. It can be trimmed using "<exclude within=..."
> but could be
> changed to only hold classes that are actually woven.
> However if you weave
> every class we need to retain a woven representation. I
> believe Adrian
> introduced the expendableMap primarily to reduce the peak
> footprint of AJDT
> during compile/weave. It allows types used purely for
> resolution to be
> released. However the references between types are not
> weak so entries in
> this map can be kept alive by types exposed to the
> weaver. This could be an
> opportunity to reduce footprint at a GC. 
> 
> However there may be a way to reduce the permanent
> reliance on byte-code for
> woven classes. Once a class has been successfully defined
> we could use
> reflection. The trick is to safely get hold of the Class
> object. If we
> control the class loader we could create a callback into
> the weaver enabling
> it to replace its byte-code representation. This is not
> possible when using
> the Java 5 agent. However in middleware environments such
> as Tomcat we could
> weave the classloaders it creates to invoke the callback
> after a successful
> define. 
> 
> As I have said before I don't think sharing information
> between weavers is
> viable because the relationship between the class loaders
> with which they
> are associated cannot be reliably determined e.g. web
> application loaders.
> The best approach is to reduce the number of JavaClass
> BCEL objects we have
> lying around by using reflection directly for bootstrap
> classes and latterly
> for woven classes. There may also be more scope for weak
> references but
> these involve indirection which can hurt performance.
> Longer term reliable,
> transparent byte-code caching will also help enormously.
> It's something I
> will be looking at as part of new Eclipse technology
> project:
>
http://www.eclipse.org/equinox/incubator/aspects/index.php.
> 
> 
> Cheers 
> 
> Matthew Webster
> AOSD Project
> Java Technology Centre, MP146
> IBM Hursley Park, Winchester,  SO21 2JN, England
> Telephone: +44 196 2816139 (external) 246139 (internal) 
> Email: Matthew Webster/UK/IBM @ IBMGB,
> matthew_webster@xxxxxxxxxx 
> http://w3.hursley.ibm.com/~websterm/ 
> Please respond to aspectj-users@xxxxxxxxxxx 
> Sent by:        aspectj-users-bounces@xxxxxxxxxxx 
> To:        <aspectj-users@xxxxxxxxxxx> 
> cc:         
> Subject:        RE: [aspectj-users] Garbage collector
> behavior 
> 
> 
> I used a recent AspectJ dev to take more measurements on
> a development
> version of my Glassbox Inspector (with a few more aspects
> than the alpha
> one). It turns out the biggest problem I'm seeing is the
> overhead per
> classloader, since Tomcat is creating one classloader per
> JSP using about
> 3MB each.
> 
> Here are the stats I'm seeing.
> 
> Memory use on startup (Tomcat 5.5 with 3 sample apps
> autostarted):
> Without weaving: 22M
> Weaving the inspector into all shared apps: 106M (after
> forcing GC)
> 
> The main memory user is the Spring 1.2.1 Web app (it has
> loaded over 900
> classes). The other app loading over 100 classes is the
> Axis server Web app
> (but less than 200).
> 
> At startup the loader for the Spring Web app has 67 type
> mungers, and over
> 800 loaded classes in world.delegate.loadedClasses, plus
> over 900
> expendableMap entries (will they ever be evicted)?
> 
> It seems surprising that it would take about 80 MB to
> hold data about 1000
> classes: does this really seem right/
> 
> I then walked through the ~15 pages of the Spring
> petclinic app.
> Unfortunately, Tomcat loads *each JSP in its own
> ClassLoader*. So the memory
> consumed went up yet again to 154M: about 3M per page
> (per class loader).
> 
> I am able to re-enable one helpful optimization that
> Matthew Webster and I
> were testing: using reflective type delegates for
> bootstrap classes instead
> of creating BCEL objects.
> 
> This takes my memory use down to 76M on startup (after
> forcing GC).
> However, after hitting all the pages, it's again up to
> 127M (after forcing
> GC). So the ~3M/classloader overhead is still about the
> same.
> 
> If I deploy a null aop.xml file in shared/lib (i.e., I
> define no aspects in
> it), then the memory use on startup is 62M even with this
> optimization.
> That's still 40M of overhead. After I visit most of the
> Petclinic pages the
> memory use is up to 75M. So it appears there's about 1M
> of overhead per
> classloader and my aspects are consuming 2M of overhead
> per classloader...
> 
> I think that weaving into Web apps is going to require
> some kind of scheme
> to share information that mirrors classloading
> hierarchies.
> 
> I'd like to find more information about where the initial
> 45M of overhead
> (200% of the total memory used without weaving) is going.
> I'd also like to
> understand how the 3M/classloader overhead breaks down.
> My next step is to
> use a memory profiler to get more data on each.
> 
> -----Original Message-----
> From: aspectj-users-bounces@xxxxxxxxxxx
> [mailto:aspectj-users-bounces@xxxxxxxxxxx] On Behalf Of
> Mathieu LEMAIRE
> Sent: Friday, October 28, 2005 7:09 AM
> To: aspectj-users@xxxxxxxxxxx
> Subject: Re: [aspectj-users] Garbage collector behavior
> 
> Hi all,
> 
> I had to bench clearly memory consumptions and cpu usage
> overheads in 
> those configs (aspect scalability, LTW / compile time W,
> no aspect at 
> all) and here is what i got :
> 
> benchmark
>                weaving                  glM (KB)        
>          tgPk (KB)
>                  ccM (KB)                  tgM
> (KB)                  glT (ms)                  gcT (ms)
> bench1                  CT few aspects                
>  70,085.41          
>        97,510.18                  26.71                
>  65,470.21 
> 15,555.11                  4,590.33
> CT many aspects                  70,064.73              
>    97,497.00      
>            26.11                  65,470.54
> 15,956.42 
> 4,509.00
> LT few aspects
>                117,904.67                  112,381.06    
>            
>  161.26                  112,381.06                
>  16,512.71
> 2,179.00
> no aspects
>                70,067.72                  97,515.85      
>            25.37  
>                65,469.83                  15,737.30
> 4,551.67
> LT many aspects
>                119,323.28                  109,141.54    
>            
>  107.46                  109,141.54                
>  18,595.90
> 2,380.67
> bench2                  CT few aspects                
>  77,874.13          
>        72,646.21                  31.59                
>  72,646.21 
> 40,059.81                  6,447.67
> CT many aspects                  75,584.27              
>    70,877.49      
>            29.85                  70,877.49
> 41,238.57 
> 6,379.33
> LT few aspects
>                103,814.15                  103,671.09    
>            
>  267.99                  93,940.62                
>  38,536.98
> 4,707.67
> no aspects
>                77,716.08                  72,481.75      
>            29.85  
>                72,481.75                  40,638.22
> 6,409.00
> LT many aspects
>                102,670.77                  104,942.94    
>            
>  238.74                  95,081.41                
>  43,023.24
> 4,337.00
> 
> 
> quick legend :
> 
>   * *glM : *globalMemoryConsumed
>   * *tgPk : *peakMemoryConsumed
>   * *ccM : *codeCacheMemoryConsumed
>   * *tgM : *tenuredGenMemoryConsumed
>   * *glT : *globalTime
>   * *gcT : *gcTime
> 
> Those marks have been done using hotspot 1.5 and new JMX
> features..
> Well those results should not stand as direct proofs but
> maybe just 
> hints on the LTW consumption.
> 
> My aspects are really simple : for profiling I do not use
> any runtime 
> check nor advanced aspectj features such as
> thisJointPoint** and when I 
> say *many* aspects, i just mean 15, compared to *few* (1)
> :)
> 
> The important thing is that the overhead resides in the
> tenured gen 
> pool, quite an old space.. that means that aspectj ltw
> still holds hard 
> references somewhere and forcing collections should not
> help with any 
> thing... Other interesting stuff is code cache
> consumption ; well I do 
> not know much about that, but ltw needs much more than
> simply 
> duplicating class defs.
> 
> The very good news is that compile time weaving do not
> introduce any 
> distorsion ; that is great for my profiling !!
> 
> hope it helps.
> -- 
> Mathieu
> 
> 
> _______________________________________________
> aspectj-users mailing list
> aspectj-users@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/aspectj-users
> 
> _______________________________________________
> aspectj-users mailing list
> aspectj-users@xxxxxxxxxxx
>
https://dev.eclipse.org/mailman/listinfo/aspectj-users______________________
> _________________________
> aspectj-users mailing list
> aspectj-users@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/aspectj-users
> 
> _______________________________________________
> aspectj-users mailing list
> aspectj-users@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/aspectj-users



Back to the top