Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[aspectj-users] Aspects holding onto weak references?


I am trying to design an aspect where I grab the stack trace when objects are constructed. I would like to display them when the objects are destroyed. I would like to do this on the call-side since the weaver may not have the source to the target object.

I'm finding that somewhere the aspect is holding a hard reference onto the target object. When I run a similar solution without using aspects, it works as expected. Any thoughts on how/why the aspect would prevent the collection of the target object?


Here's an example aspect to illustrate the problem. The problem is that the "Ref cleared" is never printed out.

public aspect WeakRefProblem {

        public static IdentityHashMap stacks = new IdentityHashMap();

        public static ReferenceQueue q = new ReferenceQueue();

        static {
                new Thread("ref clearing thread") {
                        public void run() {
                                while (true) {
                                        try {
                                                WeakReference r = (WeakReference) q.remove();
                                                Test list = (Test) r.get();
                                                System.out.println("Ref cleared");
                                                Exception e = (Exception) stacks.get(r);
                                                e.printStackTrace();
                                        } catch (InterruptedException e) {
                                                e.printStackTrace();
                                        }

                                }
                        }
                }.start();
        }

        after() returning(Test list) : call(Test+.new(..)) {
                WeakReference ref = new WeakReference(list, q);
                stacks.put(ref, new Exception());
        }

}

test program

public class Test {
        public static void main(String[] args) {

                Test t = new Test();

                t = null;
                for (int i = 0; i < 10; i++) {

                        System.gc(); // <-- this is where normally, the ref clearing thread will print out "ref cleared"
                        System.runFinalization();
                }

        }
}


Thanks,

Mindaugas Idzelis

Back to the top