The fix is to introduce a pre-enqueueing step for SATB buffers. The thread that is about to enqueue the buffer it actually iterates over it and filters out entries that are not of intrest to the marking threads (entries that point to already marked objects, entries that point to objects that have been allocated since the marking started, etc.). When a marking thread processes a buffer it skips such entries and processes the rest. What this filtering does is to get rid of most entries that the marking threads will ignore in order to cut down on the number of SATB buffers that are enqueued. At the end of the filtering operation the buffer is re-used if enough entries have been removed, or enqueued if the buffer is still reasonably full (the G1SATBBufferEnqueueingThresholdPercent parameter determines the threshold).