When a bulk API request is sent to a remote node, it currently copies off byte arrays for each request within it rather than just reusing the bytes already in the large byte array copied over to the node for the whole bulk request. This results in a lot of unnecessary garbage collection. We could instead directly use the bytes in the large shared byte array, but to do so we need to do some ref counting so that we know when we can release the shared byte array -- releasing it too early would mean corrupted requests; releasing it too late would lead to OutOfMemoryErrors.
This is going to require a good bit of work, and this ticket is just meant as a placeholder to track all of that work from a single place. The idea is that we will begin with ref counting BulkRequest objects, and work inward from there until we can safely change IndexRequest's source to read in.readReleasableBytesReference() (which reuses the underlying byte array) rather than in.readBytesReference() (which copies bytes).
The broad outline is:
Make BulkRequest RefCounted, making sure that its ref count is always zero when it is garbage collected and never zero when still in use. (#104471)
Do the same for BulkShardRequest
Do the same for the individual requests used by BulkRequest and BulkShardRequest -- BulkItemRequest, IndexRequest, UpdateRequest, and ReindexRequest.
Update IndexRequest to use the underlying shared byte array for its source
Each of those steps will be made up of several PRs.
Problem Description
When a bulk API request is sent to a remote node, it currently copies off byte arrays for each request within it rather than just reusing the bytes already in the large byte array copied over to the node for the whole bulk request. This results in a lot of unnecessary garbage collection. We could instead directly use the bytes in the large shared byte array, but to do so we need to do some ref counting so that we know when we can release the shared byte array -- releasing it too early would mean corrupted requests; releasing it too late would lead to OutOfMemoryErrors. This is going to require a good bit of work, and this ticket is just meant as a placeholder to track all of that work from a single place. The idea is that we will begin with ref counting BulkRequest objects, and work inward from there until we can safely change IndexRequest's source to read
in.readReleasableBytesReference()
(which reuses the underlying byte array) rather thanin.readBytesReference()
(which copies bytes). The broad outline is:Each of those steps will be made up of several PRs.