记CXF中的一次Non-Heap内存泄露

本文解决了一个WebService中的内存泄漏问题,通过分析发现是由于CXF中JAXB实例化引起的。问题在于CacheMap的设计,其Key为弱引用而Value为强引用,导致GC后schema仍占用内存。解决方案是将CacheMap改为HashMap。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近遇到一个WebService内存泄露的问题。使用jconsole连接后发现非堆内存和loaded classes在每次执行full GC后都会增长。classes增长的非常有规律,每次增加5000个左右。

因为CXF中使用了JAXB,怀疑是JAXB被多次实例化造成的。然后使用MAT,查找Duplicate Classes,不过MAT显示没有Duplicate Classes。

没办法,改用JVM参数追踪
* -XX:+TraceClassLoading
* -XX:+TraceClassUnloading
在trace日志中确认就是WebService相关的那些classes被多次加载了

剩下的问题就是调查哪里的JAXB被重复实例化了。跟踪发现CXF使用一个CacheMap来存储构造过的WebService类。

private static final Map<Set<Class<?>>, CachedContextAndSchemas> JAXBCONTEXT_CACHE 
    = new CacheMap<Set<Class<?>>, CachedContextAndSchemas>();

........

    synchronized (JAXBCONTEXT_CACHE) {
        cachedContextAndSchemas = JAXBCONTEXT_CACHE.get(classes);
    }
    if (cachedContextAndSchemas == null) {
        JAXBContext ctx = JAXBContext.newInstance(classes.toArray(new Class[classes.size()]), map);
        cachedContextAndSchemas = new CachedContextAndSchemas(ctx);
        synchronized (JAXBCONTEXT_CACHE) {
            JAXBCONTEXT_CACHE.put(classes, cachedContextAndSchemas);
        }
    }

CacheMap中的key是weak references,value是strong references。所以GC时候会回收对应的key,但是schema仍存留在内存中。一旦在cache中没有发现key,就会重新实例化!!

解决方法也很简单,JAXBCONTEXT_CACHE使用HashMap就可以了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值