RFR (S) CR 6857566: (bf) DirectByteBuffer garbage creation can outpace reclamation
Aleksey Shipilev
aleksey.shipilev at oracle.com
Wed Oct 2 16:38:59 UTC 2013
Hi Peter,
On 10/02/2013 07:58 PM, Peter Levart wrote:
> I briefly skimmed over the changes. If I understand them correctly,
> they change they way Cleaners are processed. Without any assistance
> from other threads, Cleaners (WeakReferences now) are 1st enqueued by
> the ReferenceHandler thread, and CleaningThread then picks them out
> of the queue and processes them. Because they are not processed by
> ReferenceHandler thread any more, cleaning does not interfere with
> en-queueing of other References. This is good.
Yes, that's the part of the story. However, no matter how many distinct
collectors you have, you can have more allocators to overwhelm them with
work. So, the major difference is that we have the feedback from the
allocators, which can assist us in claiming some of the garbage.
> Assisting cleaning from other threads means that cleaning can be
> performed in any thread. Cleaners should be prepared for that -
> previously they were only invoked from ReferenceHandler thread.
Yes. Do you see they are not? The ReferenceQueue is thread-safe, and the
Set from CHM is thread-safe as well.
> assistCleanupSlow could really become slow, if lots of Cleaners get
> allocated (for example, lots of small DirectByteBuffers get
> allocated) and not GC-ed for some time.
Yes, they can. The thing to keep in mind while looking at this code is
"graceful degradation". If ReferenceHandler is fast enough to enqueue
garbage, we have the cleanup for free by the virtue of CleanupHandler
doing the work for us. If CleanupHandler is not capable of getting the
garbage out while ReferenceHandler is still able to enqueue it,
allocators begin to assist. If the ReferenceHandler is out of capacity
to churn the garbage down, we take matters to the extreme, and begin to
scan.
> This brings me to java.nio.Bits. It uses System.gc(). I understand
> that allocation of native memory does not represent a memory
> pressure for heap GC so you're trying to trigger it when it gets
> tight.
That's not really about the heap GC. That's about forcing the reference
processing. I would instead like to ask runtime for another round of
reference processing, but at this point that is the intimate part of GC
cycle.
> But lots of environments (app servers) are using
> -XX:+DisableExplicitGC to prevent ill behaved libraries to trigger
> GCs to frequently. Have you tried your test using
> -XX:+DisableExplicitGC ?
I have not. I think in that case, the fallback strategy is screwed, and
we are heading for the (legal) OOME.
-Aleksey.
More information about the core-libs-dev
mailing list