00:01
Hello,大家好,我是小石啊,然后又和大家见面了,今天呢,跟大家分享一个我们在618当天发生的生产事故啊,就是我们线上系统OM了,正好借这个机会呢,我们来一起复盘一下如何快速排查内存溢出发生的原因啊,然后这里呢,我先弄了一个例子啊,就是我先弄了一个例子,你看我现在就是一直往那个list里面放。放bit数组,然后每次放啊,每次放一兆嘛,然后它它迟迟早会有一个迟早会OM的,然后因为我这里面设了它这个O,设了它的最大内存为30兆啊,然后这后面这两个参数是保证它发生OM的时候将。文件,嗯。嗯,当文件放到这个URL。盆这个目录下啊。后面我们会详细说的,然后我刚才已经执行了一遍,它已经生成了这个,呃,生成了这个档文件,然后我们一般分析OM的工具的话,一般有,呃,一般的话应该。
01:03
有两个嘛,但是我们最常用的就是eclipse的那个,就是Java中自带了一个,它是自带了一个,这个它自带了一个Java vm来分析啊,但是我们一般不怎么,呃,不怎么使用啊,我现在已经打开了,你就把这个文件装入刚才的MP文件。然后你看它其实提供的内容其实很小,我这里按大小排序了一下,就是可以看到占用最多的内存的话,就是这个bit数组,然后我们看一下bit数组主要的引用关系啊。对,然后就可以看到它引用关系,最终引用关系就是这个a list嘛,然后就别了,然后就没了,就是你最终只能排他到是由于a list中这个B的数组太B的数组太多了。导致的OM啊,但是你当你这个系统非常,当你这个应用非常大的时候,用这种方式,你基本上可能排查不出来,就是你排查的非常的困难,所以说我们一般的使用的话都是使用这个。
02:03
以s memory ANA,然后还是以上面例子为例啊,我就举刚才我们设的这个参数嘛,我解释一下这个参数的例子,这个就设置多多纳最大多内存的,像十二三十兆,然后这个是设置OM的时候自动生成大文件啊,然后这个是指定的路径。我们用X memory and Li来打开这个文件啊,就是它这个排查的过程就非常的轻松啊,非常的高效,然后你看啊,首先先看他总共花费了这它总共用了六二十七点二十六点七M的空间嘛,然后。可以看到它这个。所类就占了26啊26兆,然后这个其他占了600006KB啊,然后这个的话占的也很少,所以我们肯定是所类的问题啊,我们此时候此时只需要点击这个link spot,就这个就是分析内存溢溢出的啊,然后它就会跳到这个页面,它就会给你详细的这些有可能的问题啊,有可能的问题他只有目前只有一个啊,就有可能这个main线程占的太账的数量太多了,你看他占了97.21%的。
03:15
我们来看这个内线图中哪个元素对象最大呢?我们来点这个,然后它点这个数据按钮,它它会出现这个,我们来仔细看,我刚才已经点完了。所以说你就接着往下看,然后看啊,这个是97.2,然后我们接着往下看,这个a list最大,然后接着点好,看到了是由于这个list的这种bit数组导致的,你看它每个的话,它总共放了26个bit数组啊。然后每个数轴的比例。都可以看得很清楚啊,用这个的话,通过这个链路关系,你就分析的非常的高效,我们以我线上发生OM系统的这个当MP文件来为例啊,给大家分析一下好。
04:00
看我们线上系统设置的是这个1.9GB啊,1.9GB。然后呢?你看它这个sweet,这个sweet po这个线程值就占了900多兆啊,然后剩下的占了一个G啊,然后这个是这个对象,呃,Class load占了十五十六个MB啊,但是所以说肯定是这个线程池的问题啊,我们点这个还是,然后他就会弹出这个,然后他会目前的话给你有可能呢,有可能地方有三处啊,但是的话我们一眼就看出肯定是就是看一下,基本上就是第一个就是你可以看到它这个sweet pro太大了,它本身它占了47.45%。对,这个这个确实是这个占的内存太多了,我们接下来还是点这个,点这个按钮,它就会出现这个,然后来看一下它的引用关系啊。看一下他这个引用关系啊。这个是它所有的啊,然后我们来看一下这个线程值为什么这么大啊,看一下它设为看一下它的属性啊,你可以看一下它的属性,这它的核心线程池是四个,最大线程是十个,这个设置的很合理,没问题啊,然后我们来继续看啊,这个最大,然后link block queen大,然后NOENOE放了很多,你可以看看,看一下它这个就是它目前的数量是883。
05:26
个,然后它总共可以放1万个,这个就是队列式的长度有点忒大了啊,你可以看一下它,但是一个节点就是一个任务的长,一个任务的大小居然有。七兆,你,你可以理解吗?你的任务居然有七道六七道好家伙,然后我们来继续看一下他这个到底是啥。对,我就不仔细往下点了啊,因为涉及到那个报名的问题啊,我就仔细来直接看一下我这个文档啊。直接看一下我这个文档,你就可以看得很清楚啊。
06:03
嗯,你看啊,就是线程池,它占用了线程值,它占用了900多个空间,然后它主要是队列太大,一就上面分析到它就是队列占用的内存空间太大了,我们只需要往下这个点。对,然后继续往下点点点点,就你能看到这他这个引用关系嘛,然后你就可以最终的话,你就可以看到是这个d to,呃,是这个D线程中,线程中池中存放的具体的是这个d to,然后我们从这个上面中间的过程,我们猜想出这这个中间键的团队啊,将这个d to放到线程池中,然后这个线程池越来越大,越来越大。然后就把内存哦。内存溢出了啊。我来举一个例子啊,就是大概的逻辑是这样的,就是我们有一个应用程序,有一个agent agent的话每就是每个方法执行的时候就是这个agent的话会把入参后返回序列化,然后打印到日志状,然后通过flow采集日志。
07:02
然后把这些数据提供链路,链路平台监控平台等啊。然后的话就是。这个打日志的过程是异步化的,就是仓参数和返回封装成任务放到线程之中就是,然后由于618方法被高频调用,然后其中一类的d to很大,我们刚才看到了就是一个对象有六七兆啊,一个对象有六七兆,而且。它被高频调用。而且被高频调用,就是说任务一旦堆积很快就OM了啊,你看我们这个。放了一些任务很快就OM了,所以说你因为还有一个因为就是中间键它设置的不太合理,就是这个队列的最大值设置为设置了1万,但是放到八百八三十克的任务的时候,我们已经OM了,所以我们后续的解决方案就是增大老年代的大小,减少这个大对象的封装啊,这个大对象的话,不然的话每次放到象声值中,它要是一旦堆积就基本上就OM的,还有一个还有一个就是我们发现这个我们老年代设置的非常的小,你可以看啊,我们老年代就是我们系统正常运行的时候,系统正常运行的时候基本上就在基本上就是在那个崩溃的边缘了,水平线很高了,你看基本上就快溢满了,但是一就是。
08:21
流量一激增,流量一上来立马就OM了,所以说这个老年代设置的非常不合理啊,通过监控的话,我们就很快排查出问题啊。好吧,然后建议大家下去多看一下这个工,呃,多看一下这个工具啊,就是exist Mary and,这个工具真的非常非常的强大啊,能很快帮助你排查到问题,好吧,然后今天的视频就到这里了,如果有帮助到你的话,欢迎点个赞关注转发。呃,然后呢,这篇文章呢,我已经放到我的加班面试通关100分钟了,可以点击头像私信回复专栏领取啊好吧。
我来说两句