fix: cache ObjectWriter created in switch block of getObjectWriterInt…#7627
Open
Elin-Zhou wants to merge 1 commit into
Open
fix: cache ObjectWriter created in switch block of getObjectWriterInt…#7627Elin-Zhou wants to merge 1 commit into
Elin-Zhou wants to merge 1 commit into
Conversation
wenshao
reviewed
Apr 25, 2026
…ernal to prevent Metaspace leak, for issue alibaba#7626
e4bb9fc to
f905f48
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this PR does / why we need it?
ObjectWriterProvider.getObjectWriterInternal()中,switch/case 块通过GuavaSupport.createAsMapWriter()为 Guava Multimap 类型(LinkedListMultimap、ArrayListMultimap、HashMultimap、LinkedHashMultimap、TreeMultimap)创建了ObjectWriter,但创建后没有写入缓存。cache.putIfAbsent()仅存在于后续的if (objectWriter == null)分支中(line 718),而此时objectWriter已被 switch 赋值为非 null,该分支永远不会执行。这导致每次
JSON.toJSONString(guavaMultimap)都会重新创建AsMapWriter,其构造函数通过LambdaMiscCodec.createFunction()→LambdaMetafactory.metafactory()(invokestatic调用,绕过了 JVM 的ConstantCallSite缓存)生成新的 Lambda Hidden Class。这些 Hidden Class 被 ClassLoader 持有,无法被 GC 回收,造成 Metaspace 持续线性增长。生产环境每分钟调用约 15 次
JSON.toJSONString(LinkedListMultimap)),Metaspace 以约 200MB/天的速度增长,2~3 天耗尽 1024MB 上限。Summary of your change
在
getObjectWriterInternal()的 switch 块之后增加了缓存写入逻辑:复用了同方法中已有的
putIfAbsent+previous缓存模式(module 路径 line 670、通用路径 line 725)。修复后,ObjectWriter在首次创建时写入缓存,后续调用在外层getObjectWriter()的cache.get()直接命中,不再进入getObjectWriterInternal()重复创建。jstat -class验证结果:新增测试(
GuavaMultimapWriterCacheTest.java,共 11 个用例):assertSame验证两次getObjectWriter()返回同一实例)ClassLoadingMXBean的 Metaspace 泄漏回归测试Please indicate you've done the following: