問題:當(dāng) processResul 數(shù)據(jù)量很大活箕,比如有30萬條數(shù)據(jù)時(shí)候先壕,json轉(zhuǎn)換不當(dāng)會(huì)報(bào)內(nèi)存不足錯(cuò)誤嗡害。
下面是兩種方式。
gson.fromJson 常規(guī)解析
Gson gson = new Gson();
for (int i = 0; i < data.length(); i++) {
RecordDTO recordDTO = gson.fromJson(processResul, RecordDTO.class);
resultList.add(recordDTO);
}
內(nèi)存優(yōu)化版
private Map<String, Pattern> cacheCompiledRegexPatterns() {
Map<String, String> rawRegexMap = cacheRegexPatterns();
return rawRegexMap.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, entry -> Pattern.compile(entry.getValue())));
}
private void processRecord(RecordDTO recordDTO, Map<String, Pattern> regexMap) {
if (recordDTO == null) {
return;
}
// 邏輯處理略
}
private void processInBatches(List<RecordDTO> resultList, Map<String, Pattern> regexMap) {
if (resultList == null || resultList.isEmpty()) {
return;
}
// 每批次處理的最大記錄數(shù)
final int batchSize = 1000;
int totalSize = resultList.size();
// 向上取整
int numBatches = (totalSize + batchSize - 1) / batchSize;
for (int batchIndex = 0; batchIndex < numBatches; batchIndex++) {
int startIndex = batchIndex * batchSize;
int endIndex = Math.min(startIndex + batchSize, totalSize);
// 獲取當(dāng)前批次的數(shù)據(jù)
List<RecordDTO> batch = resultList.subList(startIndex, endIndex);
// 使用并行流處理批次中的每個(gè)記錄
batch.parallelStream().forEach(recordDTO -> processRecord(recordDTO, regexMap));
}
}
private List<RecordDTO> parseJsonData(String processResul) {
List<RecordDTO> resultList = new ArrayList<>();
Gson gson = new Gson();
try (JsonReader jsonReader = new JsonReader(new StringReader(processResul))) {
jsonReader.beginObject();
while (jsonReader.hasNext()) {
String name = jsonReader.nextName();
if ("data".equals(name) && jsonReader.peek() == JsonToken.BEGIN_ARRAY) {
jsonReader.beginArray();
while (jsonReader.hasNext()) {
try {
RecordDTO recordDTO = gson.fromJson(jsonReader, RecordDTO.class);
resultList.add(recordDTO);
} catch (Exception e) {
log.error("Error parsing JSON object in data array", e);
}
}
jsonReader.endArray();
} else {
jsonReader.skipValue();
}
}
jsonReader.endObject();
} catch (Exception e) {
log.error("Error parsing JSON data", e);
}
return resultList;
}
public List<RecordDTO> queryFiles(FilesReq FilesReq){
try {
String processResul = HttpUtils.httpPostWithHeadersWithoutLoggingInterceptor(queryFilesUrl, params, headerMap);
if (StringUtils.isNotEmpty(processResul)) {
JSONObject jsonObject = new JSONObject(processResul);
if (jsonObject.getInt("code") == 200) {
Map<String, Pattern> regexMap = cacheCompiledRegexPatterns();
List<RecordDTO> resultList = parseJsonData(processResul);
processInBatches(resultList, regexMap);
resultList.sort(Comparator.comparing(RecordDTO::getInvalidFile));
return resultList;
}
}
} catch (Exception e) {
log.error("查詢報(bào)錯(cuò): ",e);
}
return Collections.emptyList();
}