作者 | 码农的荒岛求生

来源 | 码农的荒岛求生(ID:escape-it)

给大家分享一个近期解决的线上问题,起因是这样的,近期参与公司的一个项目,工程量很大,代码编写测试过后终于到了紧张的上线时刻。

项目上线

上线前照例忐忑不安了一番,因为工程量比较大,预估可能不会很顺利,但还不至于到了祈祷服务器不要出bug的地步,bug对于程序员来说简直是家常便饭,没有bug反而可能会嘀咕半天,这都是职业病,没治。

紧张了一会儿,我屏气凝神,点了上线按钮,那一刻简直就像在点核按钮一样,生怕点下去后服务器会轰的一声炸掉。

结果一切正常......

这不对啊,这时博主的职业病又犯了,这么大的改动不会这么顺利吧,内存、CPU、tp99耗时一切正常,这太不正常了吧。

说曹操曹操就到

就在博主想为什么没有bug时,bug简直就像听到了我的召唤一样如约而至,博主当时甚至在想为什么梦想中的500万彩票就这么不听话呢?

上线最初一切正常,问题就出在了接下来的一段时间里。

在接下来的时间里,tp99耗时就像通货膨胀一样不可遏制的一路上扬,线上收入就像股市一样不可遏制的一路重挫。

这时博主的内心反而踏实了很多,没错,就是这个味儿,还是熟悉的配方还是熟悉的味道,I know it。

废话少说,赶紧回滚,线上恢复正常后接下来就是问题排查了。

排查问题

从监控上看,一次请求的处理时间会越来越高,那么显然问题的关键就是定位耗时出现在了哪段代码上。

没有办法,只能一点一点的去找监控了,幸好代码中监控比较丰富,一番梳理后最终锁定在了这样一行代码:

// 监控代码obj a = b;// 监控代码

这段代码本质上是在干什么呢?很简单,就是对象的copy,而且在我们的实现中还是浅copy,也就是仅仅copy了一些字段。

从监控看就是这行代码导致了tp99耗时不断上涨。

这。。这怎么可能呢?简简单单的一个对象拷贝竟然会让耗时上涨那么多,而且还是随着时间缓慢上涨,这也太神奇了吧。

当人遇到自己不能理解的问题时通常会归因于外部因素,博主也不能免俗。

接下来就是怀疑人生的时刻。

不会是监控有问题吧,不会是编译器的原因吧,不会是硬件的原因吧,不会是天气的原因的吧,不会是马上就要国庆放假的原因吧,总之不是我的原因。

一番思索后最终理性战胜了自己,哪有那么多原因,在没有其它证据下目前看就是这个对象拷贝导致的。

那么为什么一个简单的对象拷贝会导致CPU消耗越来越高,耗时越涨越多呢?

这里的关键在于意识到这一点,既然随着时间的推移耗时会越来越高,那么很显然是某个全局性质的数据随着请求的处理越堆积越多,而出问题的这个对象使用到了这个全局数据。没错,就是这样,终于要见到曙光啦,哈哈,激动!

这就解释了为什么这个对象随着时间的推移就和美债一样越滚越多,变得越来越庞大了,虽然美国政府可能没打算还美债,但是CPU拷贝越来越多的数据必然导致耗时越来越高。

找出bug

既然明确了方向,接下来就有针对性了。

首先去看一下这个对象都有哪些成员变量,对于内置类型像int、bool之类肯定不会有问题,因为这些类型的变量大小是固定的,需要注意的就是这种vector、set之类的容器。

最终经过一番检查后断定问题就是出在了某个vector成员变量上,同时也验证了上述猜想。

真相大白

问题是这样的。

这个对象的某个vector成员变量每次在处理请求时都要用另一个对象(假设为对象A)的数据来进行初始化,就像这样:

在每次处理一个请求之前,A持有的Data都会被push一些特定的数据。

而系统为了优化内存分配开销,对象A被放到了内存池中,就像这样:

由于对象被放到了内存池,因此对象A是不会被释放的,这就让对象A无形中变为了全局性质的对象。

现在,有的同学可能已经发现问题了,那就是,如果对象A在放回内存池后没有清空持有的Data,那么就会导致这样的一个问题,那就是A持有的Data随着每个请求的到来不断的被push数据,这就会导致A持有的Data就像泡沫一样越吹越大,相应的Obj对象持有的vector也会越来越大:

在这种情况下拷贝Obj对象必然要拷贝持有的vector,由于vector越来越大,因此消耗在拷贝上的时间也越来越多,使用内存池本意是好的,但由于使用完后忘记清理其保存的旧数据反而造成了内存泄漏

经验教训

这次的问题从代码编写角度看是这样的,对象A中Data字段的清理工作没有放在对象A的Clear函数,反而要靠使用者自己清理,由于代码非常复杂极其容易疏漏,博主就在这里踩坑了。。。

因此,总结下来经验教训就是:

  1. 向类中添加新成员时一定要注意其清理工作,使用前一定要确保该成员是崭新的,里面没有之前旧存货。

  2. 代码中添加必要的监控,有利于排查问题。

  3. 测试的时间要稍微长一些,否则类似这里的问题不容易暴露。

  4. 程序员遇到bug是很正常的,大胆假设,小心求证,每次问题的解决都是能力的提升。

查到问题后,修bug、自测、验证、代码提交一气呵成,再次上线就明天了,收工回家。

从下午上线发现问题到问题解决耗时超过6小时,博主到家时,已是满天繁星。

希望本文能帮助大家避开一些坑。

更多精彩推荐

☞没有 5G 版 iPhone 的苹果秋季发布会,发布了些什么?
☞2020苹果秋季发布会,你最想买什么产品?| 每日趣闻
☞大数据杀熟行为10月1日起明令禁止;阿里一号工程“犀牛制造”正式亮相;iOS 14 正式版发布 | 极客头条
☞ZooKeeper的十二连问,你顶得了嘛?
☞CSDN 创始人蒋涛解读鸿蒙:对开发者究竟意味着什么?
☞我投资比特币的3个原因
点分享点点赞点在看

意想不到,这个神奇的 Bug 让我加班到深夜相关推荐

  1. 意想不到!这个神奇的bug让我加班到深夜

    意想不到!这个神奇的bug让我加班到深夜 2021-05-30 16:07:08·马小乎 给大家分享一个近期解决的线上问题,起因是这样的,近期参与公司的一个项目,工程量很大,代码编写测试过后终于到了紧 ...

  2. 意想不到,这个神奇的bug让我加班到深夜

    Python实战社群 Java实战社群 长按识别下方二维码,按需求添加 扫码关注添加客服 进Python社群▲ 扫码关注添加客服 进Java社群▲ 作者丨码农的荒岛求生 来源丨码农的荒岛求生(esca ...

  3. 解决xib自定义tableFooterView一个神奇的bug

    最近看视频学习,做一个demo的时候碰到一个神奇的bug,后来经过各种搜索.调试和修改代码虽然把这个bug解决了,但不知道为什么.这里打算把这个过程分享出来,给大家做参考顺便也求大神来指导下. 事情是 ...

  4. 一个神奇的bug:OOM?优雅终止线程?系统内存占用较高?

    摘要:该项目是DAYU平台的数据开发(DLF),数据开发中一个重要的功能就是ETL(数据清洗).ETL由源端到目的端,中间的业务逻辑一般由用户自己编写的SQL模板实现,velocity是其中涉及的一种 ...

  5. java单例实例对象在springboot中实例化了2次,原因竟然是热部署的锅(记一次神奇的bug)

    找bug的一天 神奇的bug spring中的单例 场景 代码 产生的问题 分析 进一步分析 解决问题 参考链接 说明 神奇的bug 前言:我写的明明是单例,可是为什么初始化了二次? 今天写的这个bu ...

  6. 我的世界方块云服务器bug,我的世界当中神奇的bug,你见过哪些?

    原标题:我的世界当中神奇的bug,你见过哪些? 大家好,我是海底蛟龙4解说,今天我向大家分享一下我的世界里面的一些神奇的bug和特性,至于有人说bug还是特性,看起来都一样但还是有区别. 1.无限刷方 ...

  7. 献给半夜加班到深夜的女程序员

    相传,某软件开发公司,曾经有位很优秀的软件工程师因加班过度,死在自己的办公桌前,发现尸体已经是第二 天早上的事了,公司最终与家属私下了结,赔偿了一大笔钱,为了稳定人心,对外宣称该员工是心脏病突发而死, ...

  8. IOS7的一个神奇的Bug

    2019独角兽企业重金招聘Python工程师标准>>> 转载请注明出处 今天跟龙强兄,没事在得瑟手机,结果无意中发现一个IOS7的bug,如果iphone未设置锁屏密码,但是分别设置 ...

  9. 神奇的bug之DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP自动更新失败

    业务场景: 数据表中有一个update_time字段,设置为timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTA ...

最新文章

  1. RequisitePro SQL SERVER数据库的配置
  2. 没有导师指导,该如何自己选题发CVPR?
  3. python 自然语言处理(三)获取词性
  4. [云炬ThinkPython阅读笔记]1.4 算术运算符
  5. bzoj3140: [Hnoi2013]消毒(二分图)
  6. 论文浅尝 | GraphSAINT—基于图采样的归纳学习方法
  7. java复杂性_java – 计算Big-O复杂性
  8. 29.课时29.【Django模板】url标签使用详解(Av61533158,P29)
  9. TensorFlow 实战(三)—— 实现常见公式
  10. GooFlow有后门代码
  11. 智慧工厂 VR 拆解零件 —— Hightopo 3D 虚实现实可视化系统
  12. 联想服务器双系统安装教程,◆【双系统安装教程】小白也能看懂的双系统安装教程♀灰常简单♀(原创)◆...
  13. html p 会自动换行,css如何设置p标签不换行?
  14. 搜狗输入法的符号大全里面可以输入下标
  15. 业务中台构建--业务驱动为核心的云原生体系建设思考
  16. i tell you
  17. 阻抗和电抗的基本概念
  18. Ubuntu系统中查看电脑驱动信息
  19. 用二分法编写猜数字游戏(含:猜电脑随机数,和用户自己想的数字)python
  20. 高通平台学习----常用缩写(持续更新中)

热门文章

  1. 扛鼎之作!Twitter 图机器学习大牛发表160页论文:以几何学视角统一深度学习
  2. 曾大战LeCun的谷歌女性科学家,刚刚被Jeff Dean开除了!
  3. SAP RETAIL物料组的分配规则
  4. 产权分割商铺,太坑人!
  5. 无需「域外」文本,微软:NLP就应该针对性预训练
  6. 深度学习的光环背后,都有哪些机器学习的新进展被忽视了?
  7. 「SAP技术」SAP MM 批次管理的物料创建DN时无存储地点就不能输入批次值?
  8. 30年前过气老论文,为何能催生革命全球的CNN框架?
  9. 揭秘:人工智能迅猛发展的本质是什么?
  10. 3分钟掌握支持向量机-机器学习面试必备