分析
注: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