Use confined arena for CloseableByteBuffer (#106723)

The jdk implementation of CloseableByteBuffer currently uses a shared
arena. The assumption was that a buffer might be shared across threads.
However, in practice for compression/decompression that is not true, and
the shared arena has a noticeable impact on deallocation when the buffer
is closed. This commit switches to a confined arena, limtting buffer
creation and compress/decompress calls to a single thread.

relates #103374
This commit is contained in:
Ryan Ernst 2024-03-25 10:26:45 -07:00 committed by GitHub
parent a85599f125
commit 2196576aed
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 16 additions and 1 deletions

View file

@ -10,7 +10,16 @@ package org.elasticsearch.nativeaccess;
import java.nio.ByteBuffer;
/**
* A wrapper around a native {@link ByteBuffer} which allows that buffer to be
* closed synchronously. This is in contrast to JDK created native buffers
* which are deallocated only after GC has cleaned up references to
* the buffer.
*/
public interface CloseableByteBuffer extends AutoCloseable {
/**
* Returns the wrapped {@link ByteBuffer}.
*/
ByteBuffer buffer();
@Override

View file

@ -35,5 +35,11 @@ public interface NativeAccess {
*/
Zstd getZstd();
/**
* Creates a new {@link CloseableByteBuffer}. The buffer must be used within the same thread
* that it is created.
* @param len the number of bytes the buffer should allocate
* @return the buffer
*/
CloseableByteBuffer newBuffer(int len);
}

View file

@ -18,7 +18,7 @@ class JdkCloseableByteBuffer implements CloseableByteBuffer {
private final ByteBuffer bufferView;
JdkCloseableByteBuffer(int len) {
this.arena = Arena.ofShared();
this.arena = Arena.ofConfined();
this.bufferView = this.arena.allocate(len).asByteBuffer();
}