记一次 .NET 某招聘网后端服务 内存暴涨分析( 二 )

接下来把 string 的方法表地址传下去看看排序结果,简化输出如下:
!dumpheap -mt 000007fef8f6aee0size=29285946,count=2,totalsize=56Msize=29285540,count=2,totalsize=56Msize=29285502,count=2,totalsize=56Msize=29285348,count=2,totalsize=56Msize=27455186,count=2,totalsize=52Msize=31116504,count=1,totalsize=30Msize=31116490,count=1,totalsize=30Msize=31116306,count=1,totalsize=30Msize=31115934,count=1,totalsize=30Msize=31115920,count=1,totalsize=30Msize=31115718,count=1,totalsize=30Msize=29286342,count=1,totalsize=28Msize=29285898,count=1,totalsize=28M...Total:1198M可以看到,有不少大 size 的 string,那这些string到底是个啥,这里我随便抽几个导出到txt看看 。
0:000> !dumpheap -mt 000007fef8f6aee0 -min 0n31116490 -max 0n31116490 -short 0000000a61c510000:000> !do 0000000a61c51000 Name:System.StringMethodTable: 000007fef8f6aee0EEClass:000007fef88d3720Size:31116490(0x1daccca) bytesFile:C:windowsMicrosoft.NetassemblyGAC_64mscorlibv4.0_4.0.0.0__b77a5c561934e089mscorlib.dllString:<String is invalid or too large to print>Fields:MTFieldOffsetType VTAttrValue Name000007fef8f6dc9040000aa8System.Int321 instance15558232 m_stringLength000007fef8f6c1c840000abcSystem.Char1 instance50 m_firstChar000007fef8f6aee040000ac18System.String0sharedstatic Empty>> Domain:Value00000000003fb620:NotInit000000001ca30bd0:NotInit000000001f7b21a0:NotInit000000001f8940c0:NotInit0000000027dc46b0:NotInit00000000281bd720:NotInit00000000282b7ee0:NotInit<<0:000> .writemem D:dumpsxxxxstring.txt 0000000a61c51000 L?0x1dacccaWriting 1daccca bytes..........

记一次 .NET 某招聘网后端服务 内存暴涨分析

文章插图
 
从内容看其实就是 pdf 的 base64 编码,以同样的方式调研 char[] 和 byte[] 类型,发现大多也都是 pdf,猜测程序在处理 pdf 的过程中,进行了 byte[],char[],string 之间的切换,所以这些对象理论上大多属于无根对象,其实通过 !heapstat -iu 也能看到那大约 5.5G 的无根对象正等待GC回收 。
0:000> !heapstat -iuHeapGen0Gen1Gen2LOHHeap017625808127468047745824140181016...Total3574862562810061622296733765733004848Free space:PercentageHeap039622402411211224298616SOH: 22% LOH:0%Heap156258561449857168302152SOH: 27% LOH:0%...Heap3114485762419957312218024SOH: 25% LOH:0%Total18149278411364318258565183128Unrooted objects:PercentageHeap01216392824358442872137153536SOH: 18% LOH: 97%...Heap312368322392721435840139770656SOH:2% LOH: 99%Total1649549527948448290664805530423784三:总结本次内存阶段性暴涨的事故,主要还是程序接收了上游过多的 pdf文件,毕竟这些都是大对象,还进行了 char[],string,byte[] 的切换,造成短时间内过大的内存占用 。
最后就是我个人的解决建议:
  1. 针对大量的pdf,能否借用第三方的 oss 软件来规避一些不必要的内存占用 。
  2. 清洗服务是否可以做些限流或者使用服务均摊的方式 。
后来听朋友说,他做了筛选过滤以及一些业务流程优化解决了这个问题,我想现实中肯定有很多朋友遇到过这类问题,欢迎大家留言补充您的解决方案 。

【记一次 .NET 某招聘网后端服务 内存暴涨分析】


推荐阅读