One thing I should add is that an alternative solution to the WAR-leak
problem[2] is
repeated pooling.
The reason NetBeans did not use it, is that our performance team dislikes
repeatedly
executed tasks (you know, when various parts of the IDE wake up every 15s each
you
end up, due to # of modules, with the whole IDE being awake all the time). That
is
why all NetBeans IDE developers are discouraged to use it.
If polling was an option, one could write:
class Impl extends ReferenceQueue {}
Reference<Impl> ref = new WeakReference<Impl>(new Impl());
while (true) {
Impl impl = ref.get();
if (impl == null) {
// no other Reference objects using the Impl queue.
// exit this cleaner thread
return;
}
Reference<?> ref = impl.remove(15000);
if (ref == null) {
impl = null; // don't hold strong ref to Impl queue
System.gc(); // XXX: is anyone else holding reference to Impl queue?
continue;
}
// do something with ref
}
this could work, althrough the problem is the XXX part.
I need to release my own pointer to the Impl queue, tell the system to try to
garbage
collect it. If it has not been removed, grap new strong pointer to the Impl
queue and
wait again. I am not aware of any other way to ask for GC than System.gc, and
having
System.gc being called every 15s will likely decrease VM performance a bit.
The proper solution (no reflection, no repeated polling) would in fact be
simple: Being
able to call:
impl.remove();
without anyone having strong reference to impl - e.g. without impl being on
stack
during the remove call.
-jt
Dne Po 28. července 2014 09:23:55, Jaroslav Tulach napsal(a):
> Thanks for your reply.
>
> Dne Pá 25. července 2014 12:45:02, Brian Goetz napsal(a):
> > So, let’s start with the problem, rather than the solution.
>
> That is always better start.
>
> > Could you start
> > with writing up what issue you’re trying to address,
>
> I believe I did that in the issue description. For easier accessibility I am
> copying the text here:
>
> -----
>
> NetBeans APIs offer an "active" reference queue[1] which is automatically
> cleaned by one dedicated NetBeans thread. Once we got a bug report[2] that
> it behaves poorly when used inside of a WAR file. Whenever the WAR was
> redeployed, the number of cleanup threads increased by one, which also
> caused major memory leaks. We fixed that with a bit of reflection (nasty,
> of course). The fix worked OK, up until JDK-6853696[1] got fixed - the
> JDK-6853696 fix broke our assumptions, so now NetBeans is significantly
> broken on JDK9. I can either come up with another reflective trick[3] or be
> constructive and improve JDK to offer the functionality we need. This issue
> is my attempt to propose such JDK change.
> [1]
> http://bits.netbeans.org/8.0/javadoc/org-openide-util/org/openide/util/Util
> ities.html#activeReferenceQueue()[2] [2]
> https://netbeans.org/bugzilla/show_bug.cgi?id=206621[3]
> [3] https://netbeans.org/bugzilla/show_bug.cgi?id=245732[4]
>
> ---
>
> I am ready to provide all necessary details. I am however afraid that doing
> that over email may turn inefficient. Some iterative, question/answer,
> style may get us closer to mutual understanding.
>
> -jt
>
> > and then we can
> > proceed to evaluating whether the proposed solution is the right one?
> >
> > On Jul 24, 2014, at 7:29 AM, Jaroslav Tulach <[email protected]>
> > wrote:
> > > Hi.
> > > I'd like to add one new method into java.lang.ref.ReferenceQueue. Can
> > > anyone help me go through the review process? I've reported
> > > https://bugs.openjdk.java.net/browse/JDK-8051843
> > > but that probably is not enough, right?
> > >
> > > Thanks in advance for your help.
> > > -jt
>
> --------
> [1] https://bugs.openjdk.java.net/browse/JDK-6853696
> [2]
> http://bits.netbeans.org/8.0/javadoc/org-openide-util/org/openide/util/Util
> ities.html#activeReferenceQueue() [3]
> https://netbeans.org/bugzilla/show_bug.cgi?id=206621
> [4] https://netbeans.org/bugzilla/show_bug.cgi?id=245732