Fix heap leak: WildcardMatchingQuery retains SearchLookup via query cache#22433
Fix heap leak: WildcardMatchingQuery retains SearchLookup via query cache#22433bowenlan-amzn wants to merge 1 commit into
Conversation
41a0898 to
ecf8c8e
Compare
PR Reviewer Guide 🔍(Review updated until commit 0a948ed)Here are some key observations to aid the review process:
|
|
Persistent review updated to latest commit ecf8c8e |
PR Code Suggestions ✨Latest suggestions up to 0a948ed Explore these optional code suggestions:
Previous suggestionsSuggestions up to commit 6412ae1
Suggestions up to commit ecf8c8e
|
|
❌ Gradle check result for ecf8c8e: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
ecf8c8e to
6412ae1
Compare
|
Persistent review updated to latest commit 6412ae1 |
|
❌ Gradle check result for 6412ae1: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
…ache WildcardMatchingQuery stored a SearchLookup field and a lambda capturing QueryShardContext. When Lucene's LRUQueryCache cached these queries, the heavy per-request objects (SearchLookup, QueryShardContext, IndexSearcher, segment readers) were pinned indefinitely — ~15MB per cached pattern. Replace with valueFetcherSupplier that eagerly resolves only lightweight, index-level data (IndexFieldData or source path Set) at construction time. The scorer creates a local SourceLookup per leaf, breaking the retention chain while preserving thread safety and cache correctness. Resolves opensearch-project#22419 Signed-off-by: Bowen Lan <bowenlan@amazon.com> Signed-off-by: bowenlan-amzn <bowenlan23@gmail.com>
6412ae1 to
0a948ed
Compare
|
Persistent review updated to latest commit 0a948ed |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #22433 +/- ##
============================================
- Coverage 73.50% 73.48% -0.02%
+ Complexity 76487 76480 -7
============================================
Files 6104 6104
Lines 346567 346585 +18
Branches 49883 49886 +3
============================================
- Hits 254733 254697 -36
- Misses 71550 71585 +35
- Partials 20284 20303 +19 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Description
WildcardMatchingQuerystored aSearchLookupfield and avalueFetcherSupplierlambda that capturedQueryShardContext. When Lucene'sLRUQueryCachecached these queries, the heavy per-request objects (SearchLookup,QueryShardContext,IndexSearcher, segment readers) were pinned indefinitely — ~15 MB per cached pattern.Root cause: The lambda
() -> fieldType.valueFetcher(context, lookup, null)closes over bothcontext(QueryShardContext) andlookup(SearchLookup). SinceLRUQueryCacheretains theWildcardMatchingQueryobject, and the query holds this lambda, both heavy objects survive GC for the lifetime of the cache entry.Fix: Replace with
fieldType.valueFetcherSupplier(context)which eagerly resolves only lightweight, index-level data (IndexFieldDatafor doc-values path, orSet<String>source paths) at construction time. The scorer creates a localSourceLookupper leaf, breaking the retention chain while preserving thread safety and cache correctness.Verified with a manual cluster test (200 distinct wildcard queries, 6 reps each):
Resolves #22419
Check List
--signoffBy submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.