Skip to content

Commit 04bd6e8

Browse files
Unlink delegate in ReleasableBytesReference once ref count reaches 0 (elastic#127058)
We have some spots where we retain a reference to the `ReleasableBytesReference` instance well beyond its ref-count reaching `0`. If it itself references Netty buffers or `BigArrays` that are not pooled (mostly as a result of overflowing the pooled number of bytes for large messages or under heavy load) then those bytes are not GC-able unless we unlink them here.
1 parent b763932 commit 04bd6e8

File tree

2 files changed

+17
-6
lines changed

2 files changed

+17
-6
lines changed

server/src/main/java/org/elasticsearch/common/bytes/ReleasableBytesReference.java

+16-4
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public final class ReleasableBytesReference implements RefCounted, Releasable, B
2929

3030
private static final ReleasableBytesReference EMPTY = new ReleasableBytesReference(BytesArray.EMPTY, RefCounted.ALWAYS_REFERENCED);
3131

32-
private final BytesReference delegate;
32+
private BytesReference delegate;
3333
private final RefCounted refCounted;
3434

3535
public static ReleasableBytesReference empty() {
@@ -63,20 +63,29 @@ public boolean tryIncRef() {
6363

6464
@Override
6565
public boolean decRef() {
66-
return refCounted.decRef();
66+
boolean res = refCounted.decRef();
67+
if (res) {
68+
delegate = null;
69+
}
70+
return res;
6771
}
6872

6973
@Override
7074
public boolean hasReferences() {
71-
return refCounted.hasReferences();
75+
boolean hasRef = refCounted.hasReferences();
76+
// delegate is nulled out when the ref-count reaches zero but only via a plain store, and also we could be racing with a concurrent
77+
// decRef so need to check #refCounted again in case we run into a non-null delegate but saw a reference before
78+
assert delegate != null || refCounted.hasReferences() == false;
79+
return hasRef;
7280
}
7381

7482
public ReleasableBytesReference retain() {
75-
refCounted.incRef();
83+
refCounted.mustIncRef();
7684
return this;
7785
}
7886

7987
public ReleasableBytesReference retainedSlice(int from, int length) {
88+
assert hasReferences();
8089
if (from == 0 && length() == length) {
8190
return retain();
8291
}
@@ -128,6 +137,7 @@ public int indexOf(byte marker, int from) {
128137

129138
@Override
130139
public int length() {
140+
assert hasReferences();
131141
return delegate.length();
132142
}
133143

@@ -139,6 +149,7 @@ public BytesReference slice(int from, int length) {
139149

140150
@Override
141151
public long ramBytesUsed() {
152+
assert hasReferences();
142153
return delegate.ramBytesUsed();
143154
}
144155

@@ -213,6 +224,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
213224

214225
@Override
215226
public boolean isFragment() {
227+
assert hasReferences();
216228
return delegate.isFragment();
217229
}
218230

x-pack/plugin/security/qa/multi-cluster/src/javaRestTest/java/org/elasticsearch/xpack/remotecluster/RemoteClusterSecurityFcActionAuthorizationIT.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@
8080
import static org.elasticsearch.xpack.remotecluster.AbstractRemoteClusterSecurityTestCase.performRequestWithAdminUser;
8181
import static org.hamcrest.Matchers.arrayContaining;
8282
import static org.hamcrest.Matchers.containsString;
83-
import static org.hamcrest.Matchers.equalTo;
8483
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
8584
import static org.hamcrest.Matchers.hasSize;
8685
import static org.hamcrest.Matchers.instanceOf;
@@ -282,7 +281,7 @@ public void testIndicesPrivilegesAreEnforcedForCcrRestoreSessionActions() throws
282281
GetCcrRestoreFileChunkAction.REMOTE_TYPE,
283282
new GetCcrRestoreFileChunkRequest(response2.getNode(), sessionUUID2, leaderIndex2FileName, 1, shardId2)
284283
);
285-
assertThat(getChunkResponse.getChunk().length(), equalTo(1));
284+
assertFalse(getChunkResponse.getChunk().hasReferences());
286285

287286
// Clear restore session fails if index is unauthorized
288287
final var e4 = expectThrows(

0 commit comments

Comments
 (0)