[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] Are aspects examining the running of Threads "special" in some way for AspectJ?


 Thank you; I will try these things and report back.

Regarding the empty advice, I I did try empty advice (and also no advice) just to try to establish a baseline performance which was unaffected by aspectJ. When I did this, I wondered if "empty advice" was perhaps optimized by the AspectJ runtime into "no advice" and therefore couldn't be used as a real baseline for "minimal overhead imposed by AspectJ."

So what you seem to be saying is "even when the advice is empty, AspectJ is still processing classes as their loaded". Is that correct? That's a useful bit of information to have if it's true.

I also thought knowing whether limiting the joinpoints the pointcut woudl apply to could possibly limit the runtime overhead of applying the advice. For instance, if I explicitly limit the pointcut to joinpoints in a specific package, a statically determinable thing, does this help the LoadtimeWeaver in terms of enabling it to make fast rejections of other packages?

These are implementation questions about AspectJ I realize but I am quite interested in being able to apply AspectJ to this codebase despite its enormous size which I am pretty sure is testing the limits of what can practically be done.

Many thanks.

On 4/27/2012 7:56 PM, Andy Clement wrote:

A few things that I can initially think of:

- use jps/jstack to get the thread stacks of the JVM that you think is
hanging/going slow, is there an usual thread stack in there?

- you don't have any synchronization in your aspect for accessing the
collections.  I feel like I've had problems in the past when modifying
a collection I'm iterating over.  To tell if it is the body of your
advice that is behaving badly, just comment it all out (use empty
advice) - that will tell you if the weaving is introducing the issue
or the logic in the advice body is introducing the issue.

- The everything aspect looks ok.  I might do execution(public *
*(..)) just to reduce the output a bit, but it should be OK as you
have it.  You'd only get into issues here if you have types with loads
of methods, but then any problems would manifest as a weaving issue
(with the woven class getting too big for the JVM to handle).
Obviously instrumenting every little thing is going to have some
degree of performance impact.


On 27 April 2012 16:07, trhouse<trhouse@xxxxxxxxx> wrote:
Hi all,

I am just trying to use AspectJ to get a handle on all the threads that an
application runs. To start with, I just want to know how many there in how
many ThreadGroups.

I am using Loadtime Weaving to advise an admittedly large code base- a
popular open source IDE. Yes, it's huge.

What I am experiencing is the application "hangs" on start up without
terminating and without seeming to progress or so it seems. By "hangs" all I
mean is the application's splashscreen appears but the progress bar gets
stuck after a while and doesn't move. For half an hour, at which time I quit
the program.

It DOES work as intended - it does give me the information I am seeking, but
there just comes  a point when the output from this aspect is intermittent
and the progress bar is not moving and I can't prove it's not in long many
statement  infinite loop.

So my question is, is there something special about advising Runnable.run() that is doomed to slow everything to a crawl or get caught in an infinite loop for some reason?

The problem may be just  the sheer number of things I am trying to advise,
because the code base is so large. The only reason I don't think that   is
using another aspect, I can advise all methods and the application
successfully loads (then tells me I am out of memory and becomes uselessly
slow). The "everything" aspect is just

       pointcut captureAllMethods() : execution( * *(..));

and then I print out the signature and source location in the before() statement of the aspect.

I am sure you've all seen 1000 times before, but I included this aspect
along with the thread aspect at the bottom of this question.

Using this "everything" aspect also takes a long time but it does result ,
after many minutes, in the application being launched.

Oddly, when I apply BOTH aspects, the application I do get continuous output
from the "everything" aspect. which means it's still running.

In a slightly different version of the thread aspect, I make sure to !within
the aspect itself, just in case I was entering an infinite loop with the
aspect advising itself - something I don't see as even being possible given
the particular aspect.

I also do some System.out. printlns just to be sure that the thing is still
alive, which it is.

So I guess my other question is- have you been here before with really big
code bases? Is this just something that's bound to be unusable and the fact
that my  ( 64 bit AMD quadcore 8 gig RAM) computer runs for 45 minutes with
no sign of further progress is not a surprise to anyone?

Or is something else at work here?

Any advise is appreciated.

"Everything " aspect:
package recipePackage;

public aspect CaptureCallTargetRecipe

       pointcut captureAllMethods() : execution( * *(..))&&

// Advice declaration before() : captureAllMethods() {

             "Signature: "
                + thisJoinPoint.getStaticPart( ).getSignature( ));
             "Source Line: "
                + thisJoinPoint.getStaticPart( ).getSourceLocation( ));


--------------------------------------------------------------------------------------------------- "Thread" aspect: --------------------------------------------------------------------------------------------------- package recipePackage;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public aspect CaptureAllUniqueThreadsStartingRecipe
    static List<Thread>  threads = new ArrayList<Thread>(20);
    static List<ThreadGroup>  threadGroups = new ArrayList<ThreadGroup>(20);
    pointcut captureAllThreads(): execution(public void Runnable.run() ) ;

// Advice declaration before(): captureAllThreads() { Thread thisThread = Thread.currentThread(); if (thisThread == lastThread) { return; }

lastThread = thisThread;

                for (Iterator<Thread>  threadIterator = threads.iterator();
threadIterator.hasNext(); )
                    Thread nextThread = threadIterator.next();
                    if (thisThread == nextThread)
                        threadFound = true;


                for (Iterator<ThreadGroup>  threadGroupIterator =
threadGroups.iterator(); threadGroupIterator.hasNext(); )
                    ThreadGroup threadGroup = threadGroupIterator.next();
                    if (Thread.currentThread().getThreadGroup() ==
                        threadGroupFound = true;

System.out.println("------------------- THREAD DISCOVERED--------------------"); System.out.println("New thread discovered: " + thisThread); System.out.println("Thread List"); System.out.println("number Of Threads Created so far= " + threads.size()); System.out.println("number Of ThreadGroups Created far+ " + threadGroups.size()); System.out.println("Threads so far: ");

                int i=0;
                for (Iterator<Thread>  iterator = threads.iterator();
iterator.hasNext(); )
                    Thread nextThread = iterator.next();

                    System.out.println("Thread Name : " +
                    System.out.println("Alive? " + nextThread.isAlive());
                    System.out.println("Daemon? " + nextThread.isDaemon());
                    System.out.println("Thread Group? " +

System.out.println("------------------------------------------------------------"); }

    public volatile boolean threadFound;
    public volatile boolean threadGroupFound;
    public Thread lastThread;
    public Thread newThread;

aspectj-users mailing list
aspectj-users mailing list