【问题标题】:Do I have a JAXB classloader leak我有 JAXB 类加载器泄漏吗
【发布时间】:2011-03-16 14:46:32
【问题描述】:

我在 Glassfish 上部署了一个应用程序。随着时间的推移,加载的类数量攀升至数百万,我的 permgen 似乎也在增加。

为了帮助排除故障,我在我的 jvm 参数中添加了以下内容。 -XX:+PrintGC详情 -XX:+TraceClassUnloading -XX:+TraceClassLoading

现在在查看输出时,我看到相同的类被一遍又一遍地加载。基本上每次调用 Web 服务并使用 JAXB 来处理 xml。

[从 JVM_DefineClass 加载 com.strikeiron.ZIPCodesInRadius$JaxbAccessorF_userID] [从 JVM_DefineClass 加载 com.strikeiron.ZIPCodesInRadius$JaxbAccessorF_userID]

这是否表示泄漏?如果是,我该如何解决?

【问题讨论】:

    标签: java memory-leaks classloader permgen


    【解决方案1】:

    我发现了一个类似的线程,它描述了我遇到的相同问题。 http://forums.java.net/jive/thread.jspa?threadID=53362

    我还发现了一个错误 https://github.com/javaee/jaxb-v2/issues/581

    基本上,问题在于每次调用我的 bean 时我都在执行新的 JAXBContext("your.class.xsd")。根据错误“调用 JAXBContext.newInstance(...) 意味着重新加载所有内容,因为要(重新)使用当前或指定的类加载器。”

    解决方案是创建一个效果很好的单例。

    public enum JAXBContextSingleton {
    
    INSTANCE("your.class.xsd");
    private JAXBContext context;
    
    JAXBContextSingleton(String classToCreate) {
        try {
            this.context = JAXBContext.newInstance(classToCreate);
        } catch (JAXBException ex) {
            throw new IllegalStateException("Unbale to create JAXBContextSingleton");
        }
    }
    
    public JAXBContext getContext(){
        return context;
    }
    
    }
    

    并使用单例

    JAXBContext context = JAXBContextSingleton.INSTANCE.getContext();
    

    【讨论】:

    • 感谢您的提示,它有帮助。
    • 我们使用 Spring,所以我将 Marshallers 创建为单例 Spring bean。 JAXBContext 可以在 @PostConstruct 方法中创建,也可以延迟创建。我更喜欢第一个,因为我们的 Marshallers 被大量使用,惰性 init 在这种情况下没有意义。
    【解决方案2】:

    这是我远离 JAXB 的原因之一。我宁愿编写分别实现javax.xml.bind.Marshallerjavax.xml.bindUnmarshaller 的marshal 和unmarshal 类。我写一次就完成了。没有那种反射和动态类生成。

    【讨论】:

      猜你喜欢
      • 2017-02-26
      • 2012-03-08
      • 1970-01-01
      • 2011-02-24
      • 1970-01-01
      • 2022-11-28
      • 2021-06-06
      • 2018-11-24
      • 1970-01-01
      相关资源
      最近更新 更多