排查個jvm 內存占用持續增加的問題,紀錄一下,引以為戒。
運維發現應用jvm內存占用在發布後回落,然後持續增高,,dump後分析一下:
public <T> T getScriptedObject(String scriptName, String scriptSource, Class<T> cls) {
if (StringUtils.isEmpty(scriptSource))
throw new RuntimeException("服務腳本" + scriptName + "為空");
GroovyObject goo = null;
Class clz = null;
try {
clz = groovyClassLoader.parseClass(scriptSource);
goo = (GroovyObject) clz.newInstance();
if (null != beanFactory) {
beanFactory.autowireBeanProperties(goo, 1, true);
}
} catch (UnsatisfiedDependencyException ex) {
// ex.printStackTrace();
} catch (Exception ex) {
logger.error("腳本{}異常:{}", scriptName, ex);
throw new RuntimeException(ex);
}
if (cls.isAssignableFrom(goo.getClass())) {
return (T) goo;
} else {
throw new RuntimeException("腳本" + scriptName + "錯誤");
}
}
這個產生bean的代碼一定是多例了:
beanFactory.autowireBeanProperties(goo, 1, true);
果然:
解決方案就是在外層加一個緩存的map,來保證單例,如此就會失去腳本無發布便捷修改邏輯的優勢,所以要做一個清除map的功能,可以手動觸發,也可以定時觸發。
問題解決了,原因就是開發的時候沒有很好的理解spring api內部實現。
--------------------------
感謝一路有你~