You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用LambdaMetaFactory导致元空间泄漏的原因及解决方法

LambdaMetafactory循环调用引发元空间泄漏问题

以下是我编写的代码:

public static void main(String[] args) throws IOException, NoSuchMethodException, IllegalAccessException, LambdaConversionException {
    MethodHandles.Lookup lookup = MethodHandles.lookup();
    while (true) {
        Class<?> declaringClass = MyClass.class;
        Class<?> propertyType = List.class;
        String methodName = "getCustomerList";
        LambdaMetafactory.metafactory(lookup,
                "apply",
                MethodType.methodType(Function.class),
                MethodType.methodType(Object.class, Object.class),
                lookup.findVirtual(declaringClass, methodName, MethodType.methodType(propertyType)),
                MethodType.methodType(propertyType, declaringClass));
    }
}

public static final class MyClass {
    public List<String> getCustomerList() {
        return null;
    }
}

这段代码会无限循环调用LambdaMetafactory.metafactory,既没有保存任何变量,也没有留存返回的CallSite对象,但很快就触发了如下错误:

Caused by: java.lang.OutOfMemoryError: Compressed class space

我已进行堆转储,正如预期,堆中未发现可能引发该问题的内容,Eclipse内存分析工具也未给出任何泄漏相关的建议。

VisualVM提供的已加载类图表显示类加载数量持续上升。

我的Java版本信息:

$ java -version
openjdk version "17.0.7" 2023-04-18
OpenJDK Runtime Environment Temurin-17.0.7+7 (build 17.0.7+7)
OpenJDK 64-Bit Server VM Temurin-17.0.7+7 (build 17.0.7+7, mixed mode, sharing)

疑问

  1. 这种元空间泄漏是如何发生的?
  2. 我该如何预防?

补充测试结果

根据评论建议,在循环中添加System.gc()后,问题恶化速度显著减慢:类仍持续加载且不会被卸载,但元空间增长速度大幅降低——此前几秒就会出现OOM,现在运行10分钟后,元空间占用未超过50MB。不过元空间仍会无限增长,最终仍会触发OOM。

我还发现一个更奇怪的现象:为什么调用System.gc()能大幅减缓泄漏速度,但正常应用运行中偶尔触发Full GC,却似乎对泄漏影响不大?


内容的提问来源于stack exchange,提问作者Lukáš Petrovický

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 15:27:37