JVM环境:-Xms64m -Xmx128m
由于①mybatis的DAO接口我是传List,而mybatis的foreach底层代码是arrays的,②所以需要把List转arrays,然后遍历Arrays,③用StringBuilder拼接SQL的。
问题出现在②③步!因生成的arrays对象和StringBuilder对象是在堆内存中的,而堆内存的对象GC回收机制是:只有JVM的使用内存达到最大内存时的一定阀值,才会执行GC回收!
如果当本身JVM已经使用了占有了JVM的最大内存的90%,那么②③步的生成的对象占有内存+本身已占有的内存如果超出JVM的最大内存,而JVM又来不及执行GC时就会导致JVM内存溢出,当前线程挂掉!
我的解决方法是:实行多段相继执行,每次只批量执行3000个对象,从而保证Arrays和StringBuilder过大,当然3000个是相对于我的JVM环境而言,每个人也可以根据自身的JVM环境进行调优。上文观点是个人的理解,如果有什么不对的地方请指出,谢谢。
public int batchSave(String stockCode, String stockType, String tableNum, List<StockMarket> stockMarkets) throws Exception {
int size = stockMarkets.size();
int index = 0;
while(true) {
if(index+3000>=size) {
this.batchSave(stockType, tableNum, stockMarkets.subList(index, size-1));
break;
}else {
this.batchSave(stockType, tableNum, stockMarkets.subList(index, index+3000));
index = index+3000;
}
}
return size;
}