Skip to content

Commit 05020e6

Browse files
mgodwanbrusic
authored andcommitted
Close Zstd Dictionary after execution to avoid any memory leak. (opensearch-project#9403)
* Close Dictionary after every execution to avoid any memory leak Signed-off-by: Mohit Godwani <mgodwan@amazon.com> * Close Dictionary after every execution to avoid any memory leak Signed-off-by: Mohit Godwani <mgodwan@amazon.com> * Add changelog Signed-off-by: Mohit Godwani <mgodwan@amazon.com> --------- Signed-off-by: Mohit Godwani <mgodwan@amazon.com> Signed-off-by: Ivan Brusic <ivan.brusic@flocksafety.com>
1 parent fe1cb4c commit 05020e6

2 files changed

Lines changed: 33 additions & 29 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5050
- [Remote Store] Add Segment download stats to remotestore stats API ([#8718](https://github.com/opensearch-project/OpenSearch/pull/8718))
5151
- [Remote Store] Add remote segment transfer stats on NodesStats API ([#9168](https://github.com/opensearch-project/OpenSearch/pull/9168))
5252
- Return 409 Conflict HTTP status instead of 503 on failure to concurrently execute snapshots ([#8986](https://github.com/opensearch-project/OpenSearch/pull/5855))
53+
- Fix memory leak when using Zstd Dictionary ([#9403](https://github.com/opensearch-project/OpenSearch/pull/9403))
5354

5455
### Deprecated
5556

server/src/main/java/org/opensearch/index/codec/customcodecs/ZstdCompressionMode.java

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,13 @@ private void compress(byte[] bytes, int offset, int length, DataOutput out) thro
103103

104104
// dictionary compression first
105105
doCompress(bytes, offset, dictLength, cctx, out);
106-
cctx.loadDict(new ZstdDictCompress(bytes, offset, dictLength, compressionLevel));
106+
try (ZstdDictCompress dictCompress = new ZstdDictCompress(bytes, offset, dictLength, compressionLevel)) {
107+
cctx.loadDict(dictCompress);
107108

108-
for (int start = offset + dictLength; start < end; start += blockLength) {
109-
int l = Math.min(blockLength, end - start);
110-
doCompress(bytes, start, l, cctx, out);
109+
for (int start = offset + dictLength; start < end; start += blockLength) {
110+
int l = Math.min(blockLength, end - start);
111+
doCompress(bytes, start, l, cctx, out);
112+
}
111113
}
112114
}
113115
}
@@ -170,32 +172,33 @@ public void decompress(DataInput in, int originalLength, int offset, int length,
170172

171173
// decompress dictionary first
172174
doDecompress(in, dctx, bytes, dictLength);
173-
174-
dctx.loadDict(new ZstdDictDecompress(bytes.bytes, 0, dictLength));
175-
176-
int offsetInBlock = dictLength;
177-
int offsetInBytesRef = offset;
178-
179-
// Skip unneeded blocks
180-
while (offsetInBlock + blockLength < offset) {
181-
final int compressedLength = in.readVInt();
182-
in.skipBytes(compressedLength);
183-
offsetInBlock += blockLength;
184-
offsetInBytesRef -= blockLength;
175+
try (ZstdDictDecompress dictDecompress = new ZstdDictDecompress(bytes.bytes, 0, dictLength)) {
176+
dctx.loadDict(dictDecompress);
177+
178+
int offsetInBlock = dictLength;
179+
int offsetInBytesRef = offset;
180+
181+
// Skip unneeded blocks
182+
while (offsetInBlock + blockLength < offset) {
183+
final int compressedLength = in.readVInt();
184+
in.skipBytes(compressedLength);
185+
offsetInBlock += blockLength;
186+
offsetInBytesRef -= blockLength;
187+
}
188+
189+
// Read blocks that intersect with the interval we need
190+
while (offsetInBlock < offset + length) {
191+
bytes.bytes = ArrayUtil.grow(bytes.bytes, bytes.length + blockLength);
192+
int l = Math.min(blockLength, originalLength - offsetInBlock);
193+
doDecompress(in, dctx, bytes, l);
194+
offsetInBlock += blockLength;
195+
}
196+
197+
bytes.offset = offsetInBytesRef;
198+
bytes.length = length;
199+
200+
assert bytes.isValid() : "decompression output is corrupted";
185201
}
186-
187-
// Read blocks that intersect with the interval we need
188-
while (offsetInBlock < offset + length) {
189-
bytes.bytes = ArrayUtil.grow(bytes.bytes, bytes.length + blockLength);
190-
int l = Math.min(blockLength, originalLength - offsetInBlock);
191-
doDecompress(in, dctx, bytes, l);
192-
offsetInBlock += blockLength;
193-
}
194-
195-
bytes.offset = offsetInBytesRef;
196-
bytes.length = length;
197-
198-
assert bytes.isValid() : "decompression output is corrupted";
199202
}
200203
}
201204

0 commit comments

Comments
 (0)