[concurrency-interest] Re ference Collections

bestsss stanimir at riflexo.com
Sat Jan 7 06:19:47 EST 2012




Peter Firmstone-3 wrote:
> 
> Ok, based on the comments so far:
> 
> Reasoning about the possibility that one thread may not be able to keep
> up with a ReferenceQueue, bestsss mentioned that ReferenceQueue is a
> stack, not a queue, because it blocks while the garbage collector thread
> holds it's lock, the cleaning thread won't be able to poll(), but I
> suspect the jvm only does this a scheduled intervals.
> 
It's not a GC thread but the dedicated ReferenceHandler which gets the
enqueued references and adds them to the appropriate queues (stacks), also
executes sun.misc.Cleaner directly. It employs wait/notify and notify() is
called by the JVM itself.


Peter Firmstone-3 wrote:
> 
>     private final static ScheduledExecutorService garbageCleaner =
>             Executors.newScheduledThreadPool(1);
>     // Map to register newly created object references.
>     private final static Map<Reference,ScheduledFuture> finalizerTasks =
>             new ConcurrentHashMap<Reference,ScheduledFuture>();
>     // Finalizer queue to advise cancellation of ScheduledFuture's, 
>     // when their ReferenceProcessor has been collected.
>     private final static ReferenceQueue<Reference> phantomQueue = 
>             new ReferenceQueue<Reference>();
>     static {
>         // Finizer Task to cancel unneeded tasks.
>         garbageCleaner.scheduleAtFixedRate(
>                 new FinalizerTask(phantomQueue, finalizerTasks), 
>                 5L, 5L, TimeUnit.MINUTES
>                 );
>     }
>     
> 

I'd encourage you to pay extra attention at creating the "static" threads,
they leak resources badly - mostly thread group, context ClassLoader and
java.security.AccessControlContext (that contains reference to a classloader
too) and it has caused me truly a lot of grief. The problem occurs in
managed environments where redeploys are normal practice in long (months++)
running processes. The spawned thread will inherit and keep forever the
context class loader of the calling thread. It's absolutely random which
thread will initialize the class first. Use thread a ThreadFactory and set
the conext ClassLoader to ReferenceProcessor.class.getClassLoader() (or just
null) and try to put in thread in the "system" (or main) thread group if
there is no System.getSecurityManager(). To prevent the leaking of ACL can
do smth like AccessController.doPrivileged(...). Also you may want to
increase the thread priority but thread prir. are often ignored anyways.
Least, name the thread properly :)

JDK, itself, has problems leaking ClassLoaders (KeepAliveCache for example)
and quite a lot of other libraries suffer from the same issue, the open
sources ones are relatively easy to fix but some require heavy hacking via
reflection.
-- 
View this message in context: http://old.nabble.com/Reference-Collections-tp33078668p33097991.html
Sent from the JSR166 Concurrency mailing list archive at Nabble.com.



More information about the Concurrency-interest mailing list