企业网站好做吗,优化就是开除吗,天津装修公司哪家口碑好些,广告制作合同范本前言
不好啦❗ 天塌了❗ 系统崩了❗
快看啊#xff0c;程序outOfMemoryError了#x1f648; 我的心里活动#xff1a;“哈哈哈#x1f600;哈哈哈#x1f600;终于给我碰上了#xff0c;这个问题可很少发生啊#xff0c;又积累一个问题。虽然我昨天发了版本#xff0…前言
不好啦❗ 天塌了❗ 系统崩了❗
快看啊程序outOfMemoryError了 我的心里活动“哈哈哈哈哈哈终于给我碰上了这个问题可很少发生啊又积累一个问题。虽然我昨天发了版本但是作为公司技术最好长得最帅的我代码肯定不出现这个问题。” 不想看废话的直接看【解决过程和方案】 吧
排查过程 theme: juejin
前言
不好啦❗ 天塌了❗ 系统崩了❗
快看啊程序outOfMemoryError了 我的心里活动“哈哈哈哈哈哈终于给我碰上了这个问题可很少发生啊又积累一个问题。虽然我昨天发了版本但是作为公司技术最好长得最帅的我代码肯定不出现这个问题。” 不想看废话的直接看【解决过程和方案】 吧
排查过程 首先肯定是先看日志根据日志信息可以看到三个关键信息 1. 业务代码中调用了远程接口 2. 内存溢出outOfMemoryError 3. Arrays.copyOf(Arrays.java:3332)
猜想❔
得到关键信息后看了代码之后我就和技术经理做了一个简单的讨论 技术经理调用远程接口没有设置超时时间访问人数突然增多导致请求阻塞。瞬间一万个请求进来然后一个万的请求就阻塞了从而导致内存溢出 我的猜想请求之前没有查询大量的数据就算请求阻塞也不会占用大量内存导致outOfMemory. 还有就是Tomcat的线程池也默认200,。就算一万个请求进来同一时刻也最多处理200个请求这个200个请求都阻塞的话会造成 系统卡死但是不会出现outOfMemoryError呀 虽然抛出了一个业务代码的错误但是并不能肯定就是它引发的outOfMemoryError,也可能是其他任务占了太多内存这个请求只是一根“稻草”
解决过程和方案✔ 修改启动命令导出堆信息 定位outOfMemoryError 还得用证据说话呀! 让技术经理在启动命令上加了如下参数-XX:HeapDumpOnOutOfMemoryError -XX:HeapDumpPath./heapdump.hprof 再次出现内存溢出就会将堆信息导出。 分析堆信息定位大内存对象 因为之前已经装过分析dump文件的工具了我用的是Intellij Profiler工具打开堆快照文件如下 根本问题已经浮出水面了KbResultSet、ListUnionCustomerCheckLog这两个对象几乎把内存撑满了jvm 堆内存最大1024M 这两个就占了700M. 算是定位到问题了吧! 也推翻了技术经理说的调用远程接口大量请求被阻塞的问题。 查找GC回收日志 我们搜索自己的业务包名字就行了这样就能很快定位关键问题。发现存在service 名称 和 上面大对象的名称一致UnionCustomerCheckLog 同样的搜索方式在summary栏目搜索也能匹配上并且定位到代码方法queryXXPassList() 定位问题代码 、分析代码 找到关键代码之后我们就看看代码吧 select * 这个写法是开发禁忌哦加上这个sql 的查询的结果有40W 条了。 看看这个查询有啥用呢❓ 看看伪代码吧 下面代码就是用代码实现的分组统计…没错就是我们 Android 工程师写的因为公司去年就不用维护客户端了安卓写javaios写前端。 刚好上午给老哥指出问题下午就被人事约谈领了大礼包了。 // 查询出需要的所属数据40w条
ListUnionCustomerCheckLog xxPassList unionCustomerCheckLogService.queryXXPassList();// 分组统计
MapInteger, ListUnionCustomerCheckLog unionMap xxPassList.stream().collect(Collectors.groupingBy(UnionCustomerCheckLog::getSource));for (DictModel dict : modelList) {ChartVo vo new ChartVo();vo.setName(dict.getText());ListUnionCustomerCheckLog checkLogList unionMap.get(Integer.valueOf(dict.getValue()));if (Objects.isNull(checkLogList)) {vo.setNumber(0L);} else {// 统计长度vo.setNumber((long) checkLogList.size());}voList.add(pieChartVo);
}解决问题 既然上面已经分析出问题所在了就是Android老哥还不太会分组统计就把数据全部查询到内存中统计。导致outOfMemoryError. 解决方法修改统计改成SQL分组统计就行了 程序逻辑也相应的调整就行了。
总结
由于工程师分组统计方式错误的实现本来在数据库统计就行了然而Android老哥却全部查询出来然后再程序统计导致的内存溢出。
本篇文章分享了我去排查outOfMermoryError问题的过程希望能帮到你感谢一键三连 有趣的是上午定位到问题并确认是Android老哥写的下午老哥就被约谈了喜提大礼包。最近公司大裁员呀已经裁了三分之一了老哥们祝福我吧