1、場(chǎng)景
insertMotionDataByWxCallBack方法并發(fā)多(其實(shí)也沒(méi)多少,可能就3個(gè)?)就導(dǎo)致CPU200%了,本地沒(méi)法復(fù)現(xiàn)。
看報(bào)錯(cuò)是:java.lang.OutOfMemoryError: Metaspace,剛開(kāi)始的時(shí)候眼挫,忽略了后面的Metaspace,只看到了OutOfMemoryError,就各種找代碼問(wèn)題。
2、裝arthas
https://arthas.aliyun.com/doc/install-detail.html
cd /opt/apps/arthas/
curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar
選擇進(jìn)程
dashboard
# 查看top3的進(jìn)程號(hào)
thread -n 3
- 然后發(fā)現(xiàn),當(dāng)cpu200的時(shí)候,根據(jù)掛載不上arthas
- 建議用:https://club.kdcloud.com/article/180683020100514560?productLineId=29
top -b -d2 -n3 -H -p 1 | grep 'top -' -A 17 > slow.log && jstack -l 1 >> slow1.log
- 然后下載下來(lái)搜索進(jìn)程號(hào)
- 然后發(fā)現(xiàn)沒(méi)什么用(可能是我不會(huì)用?)如果真的要用top+jstack,一定要謹(jǐn)慎謹(jǐn)慎謹(jǐn)慎,我把機(jī)器搞崩了,你沒(méi)聽(tīng)錯(cuò),是機(jī)器,不是java進(jìn)程,機(jī)器直接掛了,ping ip都ping不通,只好斷電重啟,后面分析系統(tǒng)日志,是內(nèi)存爆了
3、分析代碼
- 沒(méi)去找Metaspace的問(wèn)題,而去找代碼了,沒(méi)想到還真找到一個(gè)問(wèn)題,但是cpu200不是這個(gè)引起的,這里也記一下
- 分析了一通代碼后,發(fā)現(xiàn)可能是文件流沒(méi)關(guān)的原因:
- 原始代碼如下:
motionApprovalReturnVO.getFileMap()如下:
private Map<String, InputStream> fileMap = new HashMap<>();
List<ContentValue.File> files = content.getValue().getFiles();
if (CollectionUtils.isNotEmpty(files)) {
List<String> fileIds = files.stream().map(ContentValue.File::getFileId).collect(Collectors.toList());
fileIds.forEach(fileId -> {
try {
File download = cpService.getMediaService().download(fileId);
motionApprovalReturnVO.getFileMap().put(download.getName(), new FileInputStream(download));
} catch (Exception e) {
LOGGER.info("getMediaService download:media_id:{} 下載失敗", fileId);
}
});
}
- 在后面調(diào)用alioss上傳也沒(méi)有close資源
private List<ILabAttachment> pullWxFile2Oss(Map<String, InputStream> fileMap) {
if (MapUtils.isEmpty(fileMap)) {
return new ArrayList<>();
}
Map<String, String> fileUrls = ossService.uploadByStream(fileMap);
return buildILabAttachment(fileUrls);
}
private List<ILabAttachment> buildILabAttachment(Map<String, String> fileUrls) {
if (MapUtils.isEmpty(fileUrls)) {
return new ArrayList<>();
}
List<ILabAttachment> iLabAttachments = new ArrayList<>();
fileUrls.forEach((fileName, url) -> {
ILabAttachment iLabAttachment = new ILabAttachment();
iLabAttachment.setName(fileName);
iLabAttachment.setUrl(url);
iLabAttachments.add(iLabAttachment);
});
return iLabAttachments;
}
- 原本是想著批量上傳能快一點(diǎn),好心辦壞事,忽略了close FileInputStream
- 修改一下代碼:
List<ContentValue.File> files = content.getValue().getFiles();
if (CollectionUtils.isNotEmpty(files)) {
List<String> fileIds = files.stream().map(ContentValue.File::getFileId).collect(Collectors.toList());
fileIds.forEach(fileId -> {
try {
File download = cpService.getMediaService().download(fileId);
try (FileInputStream inputStream = new FileInputStream(download)) {
// 處理文件流
String fileOssUrl = ossService.uploadByStream(inputStream, download.getName());
motionApprovalReturnVO.getFileUrlMap().put(download.getName(), fileOssUrl);
download.delete();
} catch (IOException e) {
// 異常處理
LOGGER.error("try (FileInputStream inputStream = new FileInputStream(download)) error");
}
} catch (Exception e) {
LOGGER.error("getMediaService download:media_id:{} 下載失敗", fileId);
}
});
}
- 用java7中的try-with-resource 語(yǔ)法來(lái)自動(dòng)釋放
- 然后發(fā)現(xiàn)依然不是這里的問(wèn)題,如果是文件導(dǎo)致的不應(yīng)該是java.lang.OutOfMemoryError: Metaspace
4、罪魁禍?zhǔn)?/h3>
- 后來(lái)本地 用VisualVM監(jiān)控了下程序,發(fā)現(xiàn)Metaspace有70M了,而服務(wù)器上jvm啟動(dòng)參數(shù)只有64M?。。。。?!
- 原來(lái)的
-XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=128m
-XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=128m
修改后文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-423039.html
-XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m
- 真實(shí)奇恥大辱,下次眼睛還是認(rèn)真一點(diǎn)看吧
end.文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-423039.html
到了這里,關(guān)于記一次javaMetaspace導(dǎo)致CPU200%的排查的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!