jvm-记录一次Metaspace溢出
分析
注:metaspace溢出不会像堆OOM溢出一样down调,mespace溢出应用还是可以正常接受请求的,但是如果处理请求需要加载新的class 但是没有足够空间会报错
可以dump信息找到无用相关类 然后找到相关对象 根据引用定位到功能代码 我是还没拿到dump信息就定位到了可疑代码
线上错误日志
原因
1.我们自己实现的duboo接口订阅导致
我们有独立版和sass版本.针对sass就是通过zookeeper调用dubbo接口,但是独立版则只有通过http调用
eweiAdminDubboHttpClient.getReference(AdminWeixinSmallAppApi.class);
因为内部缓存用的是弱引用导致大量重复订阅
public Object fetchDubboReference(Class<?> interfaceType) { if (!BudoDubboHttpUtil.useDubbo(interfaceType) || !this.getUseDubbo()) return null; // if @BudoDubboHttpExporterConfig.useDubbo() or this.useDubbo is false, skipped. final String cacheKey = "DubboReference#" + interfaceType;
//referenceCache是弱引用 Object reference = referenceCacheMap.get(cacheKey); if (null == reference) { reference = this.initDubboReference(interfaceType); referenceCacheMap.put(cacheKey, reference); } return reference; }
但是因为dubbo订阅底层是jdk动态代理 导致大量生成字节码和加载类 同时dubbo内部会缓存起来。导致被代理类得不到释放 对应class也得不到释放
变量
com.alibaba.dubbo.rpc.protocol.AbstractProtocol#invokers
jdk动态代理源码参考:
https://www.cnblogs.com/LQBlog/p/16397103.html