From 988dfa44e689eb6be4e95b91fc5d3438f40a433b Mon Sep 17 00:00:00 2001 From: Vip-Augus <850366301@qq.com> Date: Mon, 10 Jun 2019 20:06:04 +0800 Subject: [PATCH] =?UTF-8?q?=E6=89=8B=E6=8A=8A=E6=89=8B=E6=95=99=E4=BD=A0?= =?UTF-8?q?=E5=86=99=E7=94=9F=E4=BA=A7=E7=8E=AF=E5=A2=83=20OOM=20=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=20=E6=9C=AC=E4=BA=BA=E5=AE=9E=E4=B9=A0=E6=9C=9F?= =?UTF-8?q?=E5=86=99=E8=BF=87=E7=9A=84=20OOM=20=E4=BB=A3=E7=A0=81=3D-=3D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- java/OOM.java | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 java/OOM.java diff --git a/java/OOM.java b/java/OOM.java new file mode 100644 index 0000000..92e891a --- /dev/null +++ b/java/OOM.java @@ -0,0 +1,85 @@ +// 手把手教你写生产环境 OOM 代码,具体分析请看这个:https://juejin.im/post/5ce9067df265da1bc4142f18 +public Table> queryMoreAssistantSubsidiaryLedger(AssistantSubsidiaryLedgerQueryParam queryParam) { + + Table> resultTable = HashBasedTable.create(); + // 这个 list 有 2w 条数据 + for (Assistant assistant : assistants) { + + //这个 list 从数据库拿,4w 条数据,数据库交互,结合外面的看,2w * 4w,然后加上基础方法 baseQueryAssistantSubsidiaryLedgerRowsMap 的循环,线上直接 OOM 了 + List balances = balanceService.selectFromYear(customerId, accountSetId, PeriodUtils.getYear(fixedBeginPeriod)); + Map> rowMap = baseQueryAssistantSubsidiaryLedgerRowsMap( + titles, + AssistantType.fromCode(queryParam.getAssistantType()), + assistant.getId(), + fixedBeginPeriod, + endPeriod, + null, + balances); + for (Map.Entry> temp : rowMap.entrySet()) { + resultTable.put(temp.getKey(), assistant, temp.getValue()); + } + } + return resultTable; +} + +// 这是个基础方法 +private Map> baseQueryAssistantSubsidiaryLedgerRowsMap( + List titles, + AssistantType assistantType, + Integer assistantId, + String beginPeriod, + String endPeriod, + BookType ledgerType, + List balances) { + Map> resultMap = Maps.newHashMap(); + + List titleCodes = Lists.newArrayList(Lists.transform(titles, new Function() { + @Override + public String apply(CustomerAccountTitle input) { + return input.getCode(); + } + })); + + for (AssistantTitleBalance balance : balances) { + for (String titleCode : titleCodes) { + if (!balance.getAccountTitleCode().startsWith(titleCode)) { + continue; + } + List tempBalances = balanceTable.get(titleCode, year); + if (tempBalances == null) { + tempBalances = new ArrayList(); + balanceTable.put(titleCode, year, tempBalances); + } + tempBalances.add(balance); + } + } + Table> entryTable = HashBasedTable.create(); + // 这里就就恐怖了,每次查询有 2w 条数据,数据库交互 + Map documentMap = documentService.selectFromYear(beginPeriod); + for (AccountDocument document : documentMap.values()) { + // 内层遍历,每次 10 + + for (AccountEntry entry : document.getEntryList()) { + // 再遍历,最外层有 200+ + for (String titleCode : titleCodes) { + if (!entry.isUseAssistant() || AssistantType.fromCode(entry.getAssistantType()) != assistantType || !assistantId.equals(entry.getAssistantId()) || !entry.getAccountTitleCode().startsWith(titleCode)) { + continue; + } + List entries = entryTable.get(titleCode, document.getAccountPeriod()); + if (entries == null) { + entries = new ArrayList(); + entryTable.put(titleCode, document.getAccountPeriod(), entries); + } + entries.add(entry); + } + } + } + List periods = PeriodUtils.getPeriodsUpTo(beginPeriod, endPeriod); + for (CustomerAccountTitle title : titles) { + if (ledgerType != null && AccountTitleUtils.getBookType(title) == ledgerType) { + resultMap.put(title, buildSubsidiaryLedgerRows(periods, title, balanceTable.row(title.getCode()), entryTable.row(title.getCode()), documentMap, ledgerType, PeriodUtils.getIntegerYear(beginPeriod))); + } else if (ledgerType == null) { + resultMap.put(title, buildSubsidiaryLedgerRows(periods, title, balanceTable.row(title.getCode()), entryTable.row(title.getCode()), documentMap, AccountTitleUtils.getBookType(title), PeriodUtils.getIntegerYear(beginPeriod))); + } + } + return resultMap; +} \ No newline at end of file -- Gitee