zoukankan      html  css  js  c++  java
  • 记一次内存飙升的Windbg

    背景

    突然间接到运维的报警,我们一个服务,内存找过了6GB的占用。才6GB 也不是很大,因为在处理别的事情,服务dump一下暂时一放,然后半小时之后,接到了运维的Kafka堆积报警。然后切换着重启了一下两个节点,Kafka消费速率回复正常,内存也从500M攀升到2GB后逐渐稳定。当天半夜,运维又报警,不过已经熟睡的我,并没有第一时间响应,第二天观察了一下服务,发现内存已经回归到了2GB左右。

    内存飙升 与 Kafka堆积是否是一件事情

    拉出表格来对比一下时间发现,这两个事情,时间节点基本上是能对的上的,所以大概率是一件事情。


    dump分析

    这么看来只要解了内存飙升的问题,Kafka堆积的问题应该也就会一并解决。那么,我们来分析一下,为什么会出现内存飙升吧。

    首先看一下内存的整体使用情况

    !dumpheap -stat

    发现跟字符串关系很大,下边的Free应该是内存释放了,但是GC还没有及时回收的内存。

    字符串1GB + 未回收内存3GB + 其他 林林总总 约等于 6G,差不多。下面我们重点追查一下这个字符串是怎么回事。

    !DumpHeap -mt 000007fef956aee0 -min 200

    出现了大量的 500Byte左右大小的字符串。这个大小,感觉像是业务字符串,并且应该是不重复的。先随便搞一条出来看看。

    !do 000000008966ee78

    这个内容有点莫名的眼熟,这不是我们发送消息给钉钉,然后再查询一下,钉钉的消息发送结果的返回值嘛?大概已经知道,是哪段逻辑出的错了,代码虽然不是我写的,但是我大概知道有这么一段逻辑。可是这段为什么会让内存暴增呢?查一下引用堆栈。

    !GCRoot 000000008966ee78

    发现上层的引用是一个List,我们打印一下这个List看看。

    !DumpObj 0000000313b371a0

    发现这个List好像是不小,12000+。粗略算算 12000 * 500 / GB 大概 5.xGB,但是现在内存只用了1GB多点,分析一下源码。

    那个List 应该就是对应了这个tasks对象了。


    后边会把查询的数据,序列化,然后放到这个对象上,在插入到数据库中。

    简单总结一下原因,是因为一次性取出来的对象有点多(12000)条,然后挨个查询他的消息的发送结果,然后将网络调用的查询结果,序列化到对象上,然后再保存到数据库中。因为这些Model都被引用在一个List中,所以当12000个数据全都被处理完成之后才会释放List的内存。这样,每次处理,内存都跟坐过山车一样。

    问题定位到了,解决方式就很简单了,随便搞。

    啊,又解决一个问题,我变强了。

    我的掘金 https://juejin.im/post/6868466964378222599/

  • 相关阅读:
    创建struct类型的数组
    simulate windows touch input
    Could not load file using Ranorex runtime : General Questions
    UIAutomator 编译
    w3cmark前端精彩博文周报 10.27-11.2
    w3cmark前端精彩博文周报 10.20-10.27
    w3cmark前端精彩博文周报 10.13-10.19
    sublime自定义snippet代码片段
    Iconfont在移动端遇到问题的探讨
    一个小效果引出的兼容性探讨
  • 原文地址:https://www.cnblogs.com/anxin1225/p/13612802.html
Copyright © 2011-2022 走看看