jdk8 foreach創建對象優化 lambda foreach 創建對象 @Async public void asyncFullEsDoc() { List<Integer> docIdList = Arrays.asList(913,914); if (CollectionUtil.isNo ...
jdk8 foreach創建對象優化
lambda foreach 創建對象
@Async
public void asyncFullEsDoc() {
List<Integer> docIdList = Arrays.asList(913,914);
if (CollectionUtil.isNotNullOrEmpty(docIdList)){
List<Document> documents = new ArrayList<>(500);
docIdList.forEach(docId ->{
QueryKnowledgeDocResponse doc = synchronizeRedisBaseDoc(docId);
if (!StringUtils.isBlank(doc)){
Map<String, Object> docMap = BeanToMap.objectToMap(doc);
Document document = new Document();
document.setDocumentId(docId.toString()).setDocument(docMap);
documents.add(document);
}
});
...
}
}
分析,對象釋放優化
...
List<Document> documents = new ArrayList<>(500);
Document document = new Document();
docIdList.forEach(docId ->{
//用於對象釋放
document.setDocumentId(null);
document.setDocument(null);
QueryKnowledgeDocResponse doc = synchronizeRedisBaseDoc(docId);
if (!StringUtils.isBlank(doc)){
Map<String, Object> docMap = BeanToMap.objectToMap(doc);
document.setDocumentId(docId.toString()).setDocument(docMap);
documents.add(document);
}
});
...
出現的bug,最後在addList時最後一個值覆蓋了前面所有值,但是foreach中對象的每個對象值都是不同的。
分析,代碼繼續優化
...
List<Document> documents = new ArrayList<>(500);
Document document = null;
for (Integer docId: docIdList) {
document = new Document();
QueryKnowledgeDocResponse doc = synchronizeRedisBaseDoc(docId);
if (!StringUtils.isBlank(doc)){
Map<String, Object> docMap = BeanToMap.objectToMap(doc);
document.setDocumentId(docId.toString()).setDocument(docMap);
documents.add(document);
}
}
...
如果我還是想用lambda foreach 創建對象
...
List<Document> documents = new ArrayList<>(800);
final Document[] document = new Document[1];
docIdList.forEach(docId ->{
QueryKnowledgeDocResponse doc = synchronizeRedisBaseDoc(docId);
if (!StringUtils.isBlank(doc)){
Map<String, Object> docMap = BeanToMap.objectToMap(doc);
document[0] = new Document();
document[0].setDocumentId(docId.toString()).setDocument(docMap);
documents.add(document[0]);
}
});
...
分析
Object object= new Object();
寫在100個迴圈內等於你有100個引用對應了100個對象,所以100個對象在一段時間都占用記憶體,知道記憶體不足GC主動回收。
object = new Object();
寫在100個迴圈內等於你使用1個引用分別100次調用了100個對象,所以當後一個對象init後,前一個對象已經是“無引用狀態”,會很快的被GC自動回收(在你的迴圈還沒結束時,可能已經進行了多次GC回收,這點重要)
需要更好管理記憶體。