1:HL["/_next/static/css/275839517c59c532.css",{"as":"style"}] 2:HL["/_next/static/css/bdb880d990e879b6.css",{"as":"style"}] 0:[[["",{"children":["post",{"children":[["slug","node-memory-optimize","d"],{"children":["__PAGE__?{\"slug\":\"node-memory-optimize\"}",{}]}]}]},"$undefined","$undefined",true],"$L3",[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/275839517c59c532.css","precedence":"next"}],["$","link","1",{"rel":"stylesheet","href":"/_next/static/css/bdb880d990e879b6.css","precedence":"next"}]],["$L4",null]]]] 5:HL["/_next/static/css/95c7fb627fba8423.css",{"as":"style"}] 6:HL["/_next/static/css/477df780fc5cb593.css",{"as":"style"}] 7:HL["/_next/static/css/c40a92e7f996f910.css",{"as":"style"}] 3:["$L8",null] 4:[["$","meta","0",{"charSet":"utf-8"}],["$","title","1",{"children":"记一次 Node.js 内存优化"}],["$","meta","2",{"name":"description","content":"记一次 Node.js 内存优化"}],["$","link","3",{"rel":"manifest","href":"/manifest.json"}],["$","meta","4",{"name":"generator","content":"Hexo.js & Next.js"}],["$","meta","5",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","6",{"property":"og:title","content":"记一次 Node.js 内存优化"}],["$","meta","7",{"property":"og:description","content":"记一次 Node.js 内存优化"}],["$","meta","8",{"name":"twitter:card","content":"summary"}],["$","meta","9",{"name":"twitter:title","content":"记一次 Node.js 内存优化"}],["$","meta","10",{"name":"twitter:description","content":"记一次 Node.js 内存优化"}]] 9:I{"id":"7477","chunks":["194:static/chunks/194-26e3c21be498c0ce.js","859:static/chunks/859-ea023633456a13f8.js","355:static/chunks/app/tags/[slug]/page-257dc97429efd72a.js"],"name":"","async":false} a:I{"id":"92","chunks":["194:static/chunks/194-26e3c21be498c0ce.js","92:static/chunks/92-371a458fbe090447.js","284:static/chunks/284-b1d21b691d3eabee.js","605:static/chunks/app/post/[slug]/page-0339b76e369b6af8.js"],"name":"","async":false} b:I{"id":"2449","chunks":["194:static/chunks/194-26e3c21be498c0ce.js","92:static/chunks/92-371a458fbe090447.js","185:static/chunks/app/layout-4eab34e1c4d9af8d.js"],"name":"","async":false} c:I{"id":"3211","chunks":["272:static/chunks/webpack-7471fa70de6bdb29.js","253:static/chunks/bce60fc1-2413e66000a5dd8f.js","769:static/chunks/769-2bf088c0a421e73d.js"],"name":"","async":false} d:I{"id":"5767","chunks":["272:static/chunks/webpack-7471fa70de6bdb29.js","253:static/chunks/bce60fc1-2413e66000a5dd8f.js","769:static/chunks/769-2bf088c0a421e73d.js"],"name":"","async":false} f:I{"id":"6424","chunks":["194:static/chunks/194-26e3c21be498c0ce.js","92:static/chunks/92-371a458fbe090447.js","185:static/chunks/app/layout-4eab34e1c4d9af8d.js"],"name":"GaLite","async":false} 10:I{"id":"9869","chunks":["194:static/chunks/194-26e3c21be498c0ce.js","92:static/chunks/92-371a458fbe090447.js","185:static/chunks/app/layout-4eab34e1c4d9af8d.js"],"name":"SpeedInsights","async":false} 11:I{"id":"7148","chunks":["194:static/chunks/194-26e3c21be498c0ce.js","92:static/chunks/92-371a458fbe090447.js","185:static/chunks/app/layout-4eab34e1c4d9af8d.js"],"name":"Analytics","async":false} 8:["$","html",null,{"lang":"zh-CN","children":[["$","link",null,{"rel":"icon","href":"/images/icons/icon-72x72.png","type":"image/x-icon"}],["$","link",null,{"rel":"preconnect","href":"https://vip2.loli.io"}],["$","link",null,{"rel":"dns-prefetch","href":"https://vip2.loli.io"}],["$","link",null,{"rel":"alternate","type":"application/atom+xml","href":"/atom.xml"}],["$","body",null,{"children":["$","div",null,{"className":"kbCXHY jdraHW eqrBPF kEFtPS bNzOWQ juexza kXMrYr ","children":[["$","header",null,{"className":"doNOqr WhAZY cRUUAa cwMEsi dpJmjl bsTuZj iRietU JCsMI fONtwf eEsPgn gWUoqV kazZiE fsKTUV dkPCxO gdGTeM ","children":[["$","div",null,{"className":"doNOqr WhAZY hrtgtE iYRJzs iJGxaV jlwzhw ","children":[["$","$L9",null,{"className":"icyDkI gSBWlu foGVKH IVbXa kooHYa JxWnH cVJMrm hyoqRt jlijat kUpitc gdtkYW iDPWLw kayxZK hCkclF cneMsd gYPNzh ","href":"/","children":[["$","div",null,{"className":"eSltVp cpOcAb caItCN cyerGB dSxtaa lbEyiT kUPESX Pmecg ldtSOY ","children":["$","$La",null,{"src":"https://vip2.loli.io/2023/03/09/2tAMcy694lE3IZX.jpg","blurDataURL":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAIAAAACDbGyAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAW0lEQVR4nAFQAK//AAAAAA0MCD08JoiyXkqWNQBPSDHtwYf/86ehuWNAeS4Aep9O+bt9/9aWxbtzETMSAClqHld9MqambcuqdgMOAwBCaS1Mdzd/hFE4PCMEEAS4ex049PWXOAAAAABJRU5ErkJggg==","alt":"avatar","width":200,"height":200,"layout":"responsive","className":"jWjrEQ eKtERL BRobm iovjFN ","placeholder":"blur","priority":true}]}],["$","h1",null,{"className":"evYdWj cpOcAb XEVlt huiurs ","children":"fengkx's Blog"}]]}],["$","h2",null,{"id":"name","className":"hrtgtE fcXWHl ","children":"fengkx"}],["$","h3",null,{"id":"title","className":"hrtgtE fcXWHl ","children":"Student & Coder"}],["$","div",null,{"className":"fONtwf fcXWHl foGVKH IVbXa dPVLzs fkrGAA cvCecb jJGIjV ","children":[["$","svg",null,{"stroke":"currentColor","fill":"none","strokeWidth":"2","viewBox":"0 0 24 24","strokeLinecap":"round","strokeLinejoin":"round","children":["$undefined",[["$","path","0",{"d":"M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z","children":"$undefined"}],["$","circle","1",{"cx":"12","cy":"10","r":"3","children":"$undefined"}]]],"className":"$undefined","style":{"color":"$undefined"},"height":"1em","width":"1em","xmlns":"http://www.w3.org/2000/svg"}],["$","span",null,{"className":"gUpJEt ","children":"Guangzhou, China"}]]}],["$","nav",null,{"className":"hrtgtE jlwzhw gSBWlu IVbXa kKRHCo jzaqKj ehqwGF ","children":[["$","div",null,{"className":"kooHYa ","children":["$","$L9",null,{"className":"gSBWlu foGVKH fPWmiY JxWnH cVJMrm OqOoD jJbtJp ihIJmy bgUfpT AsNjI kwISoH gdPTUr eLDTYY dmKgnC dPFrWx bmQfsF krqYva kXurrt ","href":"/","children":[["$","svg",null,{"stroke":"currentColor","fill":"none","strokeWidth":"2","viewBox":"0 0 24 24","strokeLinecap":"round","strokeLinejoin":"round","className":"jJhMtm fcXWHl gdPTUr dCiVRS TTRIX ","children":["$undefined",[["$","path","0",{"d":"M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z","children":"$undefined"}],["$","polyline","1",{"points":"9 22 9 12 15 12 15 22","children":"$undefined"}]]],"style":{"color":"$undefined"},"height":"1em","width":"1em","xmlns":"http://www.w3.org/2000/svg"}],["$","span",null,{"className":"","children":"首页"}]]}]}],["$","div",null,{"className":"kooHYa ","children":["$","$L9",null,{"className":"gSBWlu foGVKH fPWmiY JxWnH cVJMrm OqOoD jJbtJp ihIJmy bgUfpT AsNjI kwISoH gdPTUr eLDTYY dmKgnC dPFrWx bmQfsF krqYva kXurrt ","href":"/archives","children":[["$","svg",null,{"stroke":"currentColor","fill":"none","strokeWidth":"2","viewBox":"0 0 24 24","strokeLinecap":"round","strokeLinejoin":"round","className":"jJhMtm fcXWHl gdPTUr dCiVRS TTRIX ","children":["$undefined",[["$","polyline","0",{"points":"21 8 21 21 3 21 3 8","children":"$undefined"}],["$","rect","1",{"x":"1","y":"3","width":"22","height":"5","children":"$undefined"}],["$","line","2",{"x1":"10","y1":"12","x2":"14","y2":"12","children":"$undefined"}]]],"style":{"color":"$undefined"},"height":"1em","width":"1em","xmlns":"http://www.w3.org/2000/svg"}],["$","span",null,{"className":"","children":"归档"}]]}]}],["$","div",null,{"className":"kooHYa ","children":["$","$L9",null,{"className":"gSBWlu foGVKH fPWmiY JxWnH cVJMrm OqOoD jJbtJp ihIJmy bgUfpT AsNjI kwISoH gdPTUr eLDTYY dmKgnC dPFrWx bmQfsF krqYva kXurrt ","href":"/tags","children":[["$","svg",null,{"stroke":"currentColor","fill":"none","strokeWidth":"2","viewBox":"0 0 24 24","strokeLinecap":"round","strokeLinejoin":"round","className":"jJhMtm fcXWHl gdPTUr dCiVRS TTRIX ","children":["$undefined",[["$","path","0",{"d":"M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z","children":"$undefined"}],["$","line","1",{"x1":"7","y1":"7","x2":"7.01","y2":"7","children":"$undefined"}]]],"style":{"color":"$undefined"},"height":"1em","width":"1em","xmlns":"http://www.w3.org/2000/svg"}],["$","span",null,{"className":"","children":"标签"}]]}]}],["$","div",null,{"className":"kooHYa ","children":["$","$L9",null,{"className":"gSBWlu foGVKH fPWmiY JxWnH cVJMrm OqOoD jJbtJp ihIJmy bgUfpT AsNjI kwISoH gdPTUr eLDTYY dmKgnC dPFrWx bmQfsF krqYva kXurrt ","href":"/links","children":[["$","svg",null,{"stroke":"currentColor","fill":"none","strokeWidth":"2","viewBox":"0 0 24 24","strokeLinecap":"round","strokeLinejoin":"round","className":"jJhMtm fcXWHl gdPTUr dCiVRS TTRIX ","children":["$undefined",[["$","path","0",{"d":"M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2","children":"$undefined"}],["$","circle","1",{"cx":"9","cy":"7","r":"4","children":"$undefined"}],["$","path","2",{"d":"M23 21v-2a4 4 0 0 0-3-3.87","children":"$undefined"}],["$","path","3",{"d":"M16 3.13a4 4 0 0 1 0 7.75","children":"$undefined"}]]],"style":{"color":"$undefined"},"height":"1em","width":"1em","xmlns":"http://www.w3.org/2000/svg"}],["$","span",null,{"className":"","children":"友链"}]]}]}],["$","div",null,{"className":"kooHYa ","children":["$","$L9",null,{"className":"gSBWlu foGVKH fPWmiY JxWnH cVJMrm OqOoD jJbtJp ihIJmy bgUfpT AsNjI kwISoH gdPTUr eLDTYY dmKgnC dPFrWx bmQfsF krqYva kXurrt ","href":"/about","children":[["$","svg",null,{"stroke":"currentColor","fill":"none","strokeWidth":"2","viewBox":"0 0 24 24","strokeLinecap":"round","strokeLinejoin":"round","className":"jJhMtm fcXWHl gdPTUr dCiVRS TTRIX ","children":["$undefined",[["$","path","0",{"d":"M18 8h1a4 4 0 0 1 0 8h-1","children":"$undefined"}],["$","path","1",{"d":"M2 8h16v9a4 4 0 0 1-4 4H6a4 4 0 0 1-4-4V8z","children":"$undefined"}],["$","line","2",{"x1":"6","y1":"1","x2":"6","y2":"4","children":"$undefined"}],["$","line","3",{"x1":"10","y1":"1","x2":"10","y2":"4","children":"$undefined"}],["$","line","4",{"x1":"14","y1":"1","x2":"14","y2":"4","children":"$undefined"}]]],"style":{"color":"$undefined"},"height":"1em","width":"1em","xmlns":"http://www.w3.org/2000/svg"}],["$","span",null,{"className":"","children":"关于"}]]}]}],["$","div",null,{"className":"kooHYa ","children":["$","$L9",null,{"className":"gSBWlu foGVKH fPWmiY JxWnH cVJMrm OqOoD jJbtJp ihIJmy bgUfpT AsNjI kwISoH gdPTUr eLDTYY dmKgnC dPFrWx bmQfsF krqYva kXurrt ","href":"/search","children":[["$","svg",null,{"stroke":"currentColor","fill":"none","strokeWidth":"2","viewBox":"0 0 24 24","strokeLinecap":"round","strokeLinejoin":"round","className":"cpOcAb gdPTUr dCiVRS TTRIX ","children":["$undefined",[["$","circle","0",{"cx":"11","cy":"11","r":"8","children":"$undefined"}],["$","line","1",{"x1":"21","y1":"21","x2":"16.65","y2":"16.65","children":"$undefined"}]]],"style":{"color":"$undefined"},"height":"1em","width":"1em","xmlns":"http://www.w3.org/2000/svg"}],["$","span",null,{"className":"jJhMtm fcXWHl ","children":"搜索"}]]}]}],["$","div",null,{"className":"kooHYa evYdWj ","children":["$","$L9",null,{"className":"gSBWlu foGVKH fPWmiY JxWnH cVJMrm OqOoD jJbtJp ihIJmy bgUfpT AsNjI kwISoH gdPTUr eLDTYY dmKgnC dPFrWx bmQfsF krqYva kXurrt ","href":"/atom.xml","prefetch":false,"children":[["$","svg",null,{"stroke":"currentColor","fill":"none","strokeWidth":"2","viewBox":"0 0 24 24","strokeLinecap":"round","strokeLinejoin":"round","className":"cpOcAb gdPTUr dCiVRS TTRIX ","children":["$undefined",[["$","path","0",{"d":"M4 11a9 9 0 0 1 9 9","children":"$undefined"}],["$","path","1",{"d":"M4 4a16 16 0 0 1 16 16","children":"$undefined"}],["$","circle","2",{"cx":"5","cy":"19","r":"1","children":"$undefined"}]]],"style":{"color":"$undefined"},"height":"1em","width":"1em","xmlns":"http://www.w3.org/2000/svg"}],["$","span",null,{"className":"jJhMtm fcXWHl ","children":"RSS"}]]}]}]]}]]}],["$","div",null,{"className":"doNOqr hrtgtE fcXWHl iigETV bMSzLf XEVlt jmezSN izetJs kdrTtD bLIxaN ","children":[["$","div",null,{"className":"iLYBKc gSBWlu zEGrF evYWGf hDdCaA ","children":[["$","$L9",null,{"title":"fengkx's GitHub","href":"https://github.com/fengkx","prefetch":false,"children":["$","svg",null,{"stroke":"currentColor","fill":"none","strokeWidth":"2","viewBox":"0 0 24 24","strokeLinecap":"round","strokeLinejoin":"round","children":["$undefined",[["$","path","0",{"d":"M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22","children":"$undefined"}]]],"className":"$undefined","style":{"color":"$undefined"},"height":"1em","width":"1em","xmlns":"http://www.w3.org/2000/svg"}]}],["$","$L9",null,{"title":"fengkx's Telegram","href":"https://t.me/fengkx","prefetch":false,"children":["$","svg",null,{"stroke":"currentColor","fill":"none","strokeWidth":"2","viewBox":"0 0 24 24","strokeLinecap":"round","strokeLinejoin":"round","children":["$undefined",[["$","line","0",{"x1":"22","y1":"2","x2":"11","y2":"13","children":"$undefined"}],["$","polygon","1",{"points":"22 2 15 22 11 13 2 9 22 2","children":"$undefined"}]]],"className":"$undefined","style":{"color":"$undefined"},"height":"1em","width":"1em","xmlns":"http://www.w3.org/2000/svg"}]}],["$","$L9",null,{"href":"https://mstdn.social/@fengkx","rel":"me","prefetch":false,"children":["$","svg",null,{"stroke":"currentColor","fill":"none","strokeWidth":"2","viewBox":"0 0 24 24","strokeLinecap":"round","strokeLinejoin":"round","children":["$undefined",[["$","path","0",{"stroke":"none","d":"M0 0h24v24H0z","fill":"none","children":"$undefined"}],["$","path","1",{"d":"M18.648 15.254c-1.816 1.763 -6.648 1.626 -6.648 1.626a18.262 18.262 0 0 1 -3.288 -.256c1.127 1.985 4.12 2.81 8.982 2.475c-1.945 2.013 -13.598 5.257 -13.668 -7.636l-.026 -1.154c0 -3.036 .023 -4.115 1.352 -5.633c1.671 -1.91 6.648 -1.666 6.648 -1.666s4.977 -.243 6.648 1.667c1.329 1.518 1.352 2.597 1.352 5.633s-.456 4.074 -1.352 4.944z","children":"$undefined"}],["$","path","2",{"d":"M12 11.204v-2.926c0 -1.258 -.895 -2.278 -2 -2.278s-2 1.02 -2 2.278v4.722m4 -4.722c0 -1.258 .895 -2.278 2 -2.278s2 1.02 2 2.278v4.722","children":"$undefined"}]]],"className":"$undefined","style":{"color":"$undefined"},"height":"1em","width":"1em","xmlns":"http://www.w3.org/2000/svg"}]}],["$","$L9",null,{"title":"RSS feed","href":"/atom.xml","prefetch":false,"children":["$","svg",null,{"stroke":"currentColor","fill":"none","strokeWidth":"2","viewBox":"0 0 24 24","strokeLinecap":"round","strokeLinejoin":"round","children":["$undefined",[["$","path","0",{"d":"M4 11a9 9 0 0 1 9 9","children":"$undefined"}],["$","path","1",{"d":"M4 4a16 16 0 0 1 16 16","children":"$undefined"}],["$","circle","2",{"cx":"5","cy":"19","r":"1","children":"$undefined"}]]],"className":"$undefined","style":{"color":"$undefined"},"height":"1em","width":"1em","xmlns":"http://www.w3.org/2000/svg"}]}]]}],["$","div",null,{"className":"hrtgtE fcXWHl cyerGB kKRHCo ","children":["Build with ",["$","$L9",null,{"title":"Hexo official site","rel":"noopener noreferrer external nofollow","href":"https://hexo.io","children":"Hexo"}]," ","and"," ",["$","$L9",null,{"title":"Next.js official site","href":"https://nextjs.org","rel":"noopener noreferrer external nofollow","children":"Next.js"}]]}]]}]]}],["$","$Lb",null,{"children":["$","$Lc",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","loading":"$undefined","loadingStyles":"$undefined","hasLoading":false,"template":["$","$Ld",null,{}],"templateStyles":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined","childProp":{"current":["$","$Lc",null,{"parallelRouterKey":"children","segmentPath":["children","post","children"],"error":"$undefined","errorStyles":"$undefined","loading":"$undefined","loadingStyles":"$undefined","hasLoading":false,"template":["$","$Ld",null,{}],"templateStyles":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined","childProp":{"current":["$","$Lc",null,{"parallelRouterKey":"children","segmentPath":["children","post","children",["slug","node-memory-optimize","d"],"children"],"error":"$undefined","errorStyles":"$undefined","loading":"$undefined","loadingStyles":"$undefined","hasLoading":false,"template":["$","$Ld",null,{}],"templateStyles":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined","childProp":{"current":["$Le",null],"segment":"__PAGE__?{\"slug\":\"node-memory-optimize\"}"},"styles":[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/275839517c59c532.css","precedence":"next"}],["$","link","1",{"rel":"stylesheet","href":"/_next/static/css/95c7fb627fba8423.css","precedence":"next"}],["$","link","2",{"rel":"stylesheet","href":"/_next/static/css/477df780fc5cb593.css","precedence":"next"}],["$","link","3",{"rel":"stylesheet","href":"/_next/static/css/c40a92e7f996f910.css","precedence":"next"}]]}],"segment":["slug","node-memory-optimize","d"]},"styles":[]}],"segment":"post"},"styles":[]}]}],["$","$Lf",null,{"uaId":"UA-103237573-1"}],["$","$L10",null,{}],["$","$L11",null,{}]]}]}]]}] 13:I{"id":"5307","chunks":["194:static/chunks/194-26e3c21be498c0ce.js","92:static/chunks/92-371a458fbe090447.js","284:static/chunks/284-b1d21b691d3eabee.js","605:static/chunks/app/post/[slug]/page-0339b76e369b6af8.js"],"name":"TocTitle","async":false} e:[false,["$","main",null,{"className":"prose eUUCKp kTeytq jmezSN cjScYX eqrBPF jdraHW cRUUAa DOWJl hgvoZN iZwowi jGHqUK kwISoH AsNjI","children":[["$","h1",null,{"className":"EKhXX ","children":"记一次 Node.js 内存优化"}],"$L12"]}],["$","aside",null,{"className":"cwMEsi dpJmjl gWUoqV kazZiE fsKTUV dkPCxO fcXWHl hrtgtE icKiSN eeREmo fZMRmg hRjOno ","children":["$","div",null,{"className":"doNOqr gepZXl AsideContainer_asideContainer___FNWl","children":["$","div",null,{"className":"bKqOie lkcNSa doNOqr dNtEOi ","children":[["$","div",null,{"className":"hlBtvm ckBWJI XEVlt ","children":"文章目录"}],["$","div",null,{"className":"$undefined","children":["$","ol",null,{"className":"jOeduE ","children":[["$","li",null,{"children":[["$","$L13",null,{"id":"现状-起因","text":"现状/起因"}],false]}],["$","li",null,{"children":[["$","$L13",null,{"id":"排查","text":"排查"}],["$","ol",null,{"className":"jOeduE iDuqPI ","children":[["$","li",null,{"children":[["$","$L13",null,{"id":"工具","text":"工具"}],false]}]]}]]}],["$","li",null,{"children":[["$","$L13",null,{"id":"String-占用","text":"String 占用"}],["$","ol",null,{"className":"jOeduE iDuqPI ","children":[["$","li",null,{"children":[["$","$L13",null,{"id":"解决","text":"解决"}],false]}]]}]]}],["$","li",null,{"children":[["$","$L13",null,{"id":"p-map-fastq","text":"p-map => fastq"}],["$","ol",null,{"className":"jOeduE iDuqPI ","children":[["$","li",null,{"children":[["$","$L13",null,{"id":"解决-2","text":"解决"}],false]}]]}]]}],["$","li",null,{"children":[["$","$L13",null,{"id":"进一步优化","text":"进一步优化"}],["$","ol",null,{"className":"jOeduE iDuqPI ","children":[["$","li",null,{"children":[["$","$L13",null,{"id":"Manual-gc","text":"Manual gc"}],false]}]]}]]}],["$","li",null,{"children":[["$","$L13",null,{"id":"检查-workQueue-情况","text":"检查 workQueue 情况"}],false]}],["$","li",null,{"children":[["$","$L13",null,{"id":"总结感受","text":"总结感受"}],["$","ol",null,{"className":"jOeduE iDuqPI ","children":[["$","li",null,{"children":[["$","$L13",null,{"id":"未来展望","text":"未来展望"}],false]}]]}]]}]]}]}]]}]}]}]] 14:I{"id":"4998","chunks":["194:static/chunks/194-26e3c21be498c0ce.js","92:static/chunks/92-371a458fbe090447.js","284:static/chunks/284-b1d21b691d3eabee.js","605:static/chunks/app/post/[slug]/page-0339b76e369b6af8.js"],"name":"ArticleContentClient","async":false} 15:I{"id":"7974","chunks":["194:static/chunks/194-26e3c21be498c0ce.js","92:static/chunks/92-371a458fbe090447.js","284:static/chunks/284-b1d21b691d3eabee.js","605:static/chunks/app/post/[slug]/page-0339b76e369b6af8.js"],"name":"H1","async":false} 1b:I{"id":"7974","chunks":["194:static/chunks/194-26e3c21be498c0ce.js","92:static/chunks/92-371a458fbe090447.js","284:static/chunks/284-b1d21b691d3eabee.js","605:static/chunks/app/post/[slug]/page-0339b76e369b6af8.js"],"name":"H2","async":false} 20:I{"id":"7974","chunks":["194:static/chunks/194-26e3c21be498c0ce.js","92:static/chunks/92-371a458fbe090447.js","284:static/chunks/284-b1d21b691d3eabee.js","605:static/chunks/app/post/[slug]/page-0339b76e369b6af8.js"],"name":"H3","async":false} 12:["$","$L14",null,{"permalink":"https://www.fengkx.top/post/node-memory-optimize/","dateString":"2020-11-18","comments":true,"aplayer":false,"showCopyright":true,"children":[["$","$L15","1644",{"id":"现状-起因","children":["现状 / 起因"]}],"\n",["$","p","1650",{"children":["$L16","的公开 Demo ","$L17"," 随着项目的开源一同上线。也运行了有将近两年了。截至今日(2020/11/18)Demo 有活跃订阅源 3900 + 个。Demo 用 docker 部署在了一台 1C1G 的","$L18","主机上,设定为每十五分钟抓取一次。由于每 15 分钟需要抓取 3k + 的源地址是一个不太轻松的活,抓取的部分是单独使用一个 child_process 进行的。随着订阅数的增长,代码中的一些问题也显现了出来。近期发现","$L19","占用的内存相当的高。特别是在网络不畅通的环境(比如墙内),因为","$L1a","的重试和超时机制,内存占用甚至会突破 Node.js 的限制而导致进程退出。"]}],"\n",["$","$L15","1651",{"id":"排查","children":["排查"]}],"\n",["$","$L1b","1652",{"id":"工具","children":["工具"]}],"\n",["$","p","1656",{"children":["排查内存占用,首先需要找出哪些东西占用了内存。这就用到了 Chrome Dev Tool 中的 memory 面板,在这里可以加载 v8 的 heapsnapshot 并且提供总览,比较等的视图来查找内存占用(被持有)的原因。具体的用法可以看","$L1c","在这里不在赘述。但是官方文档中有部分的东西并没有说的很清楚。比如比较视图的表头几个带",["$","code","1654",{"children":["#"]}],"号的含义就困扰了我一阵子。在 tg 群友的推荐下收获","$L1d","是个很好的补充。"]}],"\n",["$","p","1658",{"children":["Node.js 12 中加入了","$L1e","选项,可以用来生成 heapshot。"]}],"\n",["$","$L1b","1659",{"id":"String-占用","children":["String 占用"]}],"\n",["$","p","1662",{"children":["找出内存占用最快的方式莫过于将一大一小两个 snapshot 放到对比视图中看差值。",["$","code","1660",{"children":["kill"]}]," 一番之后收获",["$","code","1661",{"children":[".heapsnapshot"]}],"两个。"]}],"\n",["$","p","1664",{"children":[["$","$La",null,{"className":"m-img","id":"$undefined","alt":"online-snapshot-compare","style":"$undefined","loading":"lazy","src":"https://vip2.loli.io/2023/03/08/OU5mGByoMbc7iS1.png","width":1162,"height":310,"placeholder":"blur","blurDataURL":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAABCAIAAACZnPOkAAAACXBIWXMAABJ0AAASdAHeZh94AAAAGUlEQVR4nGMwMDB49OjRt2/fpk6dmpSUDABHKgj//wjlrAAAAABJRU5ErkJggg=="}]]}],"\n",["$","p","1668",{"children":["可以看出字符串占了很多,比起别的多了一个数量级。具体来说是 feed 的 xml。下面第二大的 ArrayBufferData 也是同样的东西占的最多。具体到代码的话就是","$L1f","中的",["$","code","1666",{"children":["body"]}],"和",["$","code","1667",{"children":["rawBody"]}],"。"]}],"\n",["$","p","1670",{"children":["找到问题了,挑选一个幸运儿,根据幸运儿的 Retainers 调整代码。直到 res 这两个属性的引用全部被 delete。本地运行",["$","code","1669",{"children":["fetch.js"]}],"分析 snapshot。"]}],"\n",["$","p","1672",{"children":[["$","$La",null,{"className":"m-img","id":"$undefined","alt":"sliced-string","style":"$undefined","loading":"lazy","src":"https://vip2.loli.io/2023/03/08/nfQaNPEixms4d53.jpg","width":423,"height":811,"placeholder":"blur","blurDataURL":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAIAAAAPE8H1AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAM0lEQVR4nGMwM7U0NTJWUVJl4BRTlFTRN7LzZVi/ft2qlSu/ffvGMA0MPn/5wnAKDIBiAKZjF/ocUoLQAAAAAElFTkSuQmCC"}]]}],"\n",["$","p","1675",{"children":["但是发现一个问题,rss-parser 使用的 xml2js 解析整一个 xml string。rss 中的很多 field",["$","code","1673",{"children":["content"]}],",",["$","code","1674",{"children":["title"]}],"等都是这个 string 的 slice。即便除了 sliced string 没有任何别的 retainer,这个 string 也没有被 gc。由于 string 是 read only 的,所以这样的优化有助于计算性能。但是在 RSSBot 中就非常致命了。一个 feed 小的也有几百 KB,snapshot 中看到最大的能有 7M。"]}],"\n",["$","$L20","1676",{"id":"解决","children":["解决"]}],"\n",["$","p","1680",{"children":["考虑到我完全不需要 rss 中除",["$","code","1677",{"children":["title"]}],", ",["$","code","1678",{"children":["link"]}],"之外的其他 field。所以我决定直接把 rss-parser 拿掉,换用","$L21","正如 camaro 作者在 README 中写的一样"]}],"\n",["$","blockquote","1682",{"children":["\n",["$","p","1681",{"children":["The whole reason of me creating this is because most of the time, I’m just interested in some of the data in the whole XML mess."]}],"\n"]}],"\n",["$","p","1684",{"children":[["$","$La",null,{"className":"m-img","id":"$undefined","alt":"after-camaro","style":"$undefined","loading":"lazy","src":"https://vip2.loli.io/2023/03/08/Akz2cTOs67E9C4q.png","width":258,"height":266,"placeholder":"blur","blurDataURL":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAIAAAACDbGyAAAACXBIWXMAABJ0AAASdAHeZh94AAAAW0lEQVR4nAFQAK//ANfZ2vDw8Pv7+/7+/v7+/gDR1NLAwcHT1NXg4uLs7e0A1dTLwr653dvX7evl+PbzAKu0uZumr6q0w7rH19Ld6wAAQnIAO3cAJXAADFsAPIDaizXyTwTvzgAAAABJRU5ErkJggg=="}]]}],"\n",["$","p","1685",{"children":["考虑到两次 snapshot 的时间间隔不一致,这样的效果也算是个不小的提升了。但是运行时间长了的话 heap 还是会上到 400MB。还有改进的空间。"]}],"\n",["$","$L1b","1686",{"id":"p-map-fastq","children":["p-map => fastq"]}],"\n",["$","p","1688",{"children":[["$","$La",null,{"className":"m-img","id":"$undefined","alt":"array-obj-memory","style":"$undefined","loading":"lazy","src":"https://vip2.loli.io/2023/03/08/I7SaPQ31i5mBus6.png","width":908,"height":822,"placeholder":"blur","blurDataURL":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAIAAAACDbGyAAAACXBIWXMAABJ0AAASdAHeZh94AAAAW0lEQVR4nAFQAK//AAAGFAMQGigyPSEqNC01PQBXWWJKS1N+gImKkZtrcXcAv7m5n5ORxb269/bzy8vKAHNyc4R/f56bm7a2tpaWlgBZWFmcnZ3q6+u4uLhmZmbJcCWDHrxn6AAAAABJRU5ErkJggg=="}]]}],"\n",["$","p","1692",{"children":["$L22","中使用 p-map 控制请求的并发数量。本来以为不会出现如此长的数组。但阅读 p-map 源码之后发现,",["$","code","1690",{"children":["p-map"]}]," 并不等于任务队列,整个数组和结果数组都会保存起来。",["$","s","1691",{"children":["(废话)不然怎么叫 map"]}]]}],"\n",["$","$L20","1693",{"id":"解决-2","children":["解决"]}],"\n",["$","p","1696",{"children":["是误用了,换掉。我没有选择换成同一系列的",["$","code","1694",{"children":["p-queue"]}],", 因为他的 api 设计不太合适。然后找到了","$L23",", 作者,stars,used by 看下来,再看一下代码。靠谱!果断换掉。"]}],"\n",["$","p","1698",{"children":[["$","$La",null,{"className":"m-img","id":"$undefined","alt":"fastq-snapshots.png","style":"$undefined","loading":"lazy","src":"https://vip2.loli.io/2023/03/08/7HZyDJhbqoKkS35.png","width":256,"height":157,"placeholder":"blur","blurDataURL":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAADCAIAAADUVFKvAAAACXBIWXMAABJ0AAASdAHeZh94AAAANUlEQVR4nGOQkpFgZmYwNjbetWvX0aNHGVRUFdnZmK2trY8ePfr06VMGM3NjDQ21sLBwCB8AbLESq8aYjXsAAAAASUVORK5CYII="}]]}],"\n",["$","p","1699",{"children":["一切看起来是这么的美好~"]}],"\n",["$","$L1b","1700",{"id":"进一步优化","children":["进一步优化"]}],"\n",["$","$L20","1701",{"id":"Manual-gc","children":["Manual gc"]}],"\n",["$","p","1706",{"children":["继续找占用内存的根源,发现还是有一些 xml string 阴魂不散。仔细检查 snapshot,确实应该要被 gc 才对的。于是决定手动 tigger gc。Node.js 提供 ",["$","code","1702",{"children":["--exposed-gc"]}],"选项。在 child_process 的 execArgv 中加上就能使用",["$","code","1703",{"children":["global.gc"]}],"手动触发 gc。递归调用",["$","code","1704",{"children":["setTimeout"]}],"做一个定时 3 分钟一次的 gc。效果显著,snapshot 再也没有阴魂不散的 xml string 了。",["$","br","1705",{}],"\n在本地长期运行,关闭代理模拟大量 feed 出错的情况,多次触发 snapshot,gc 后的 heap 大小表现还是很不错的。"]}],"\n",["$","p","1708",{"children":[["$","$La",null,{"className":"m-img","id":"$undefined","alt":"prod-snapshots","style":"$undefined","loading":"lazy","src":"https://vip2.loli.io/2023/03/08/LAgy1nSZ9DpQRdj.png","width":261,"height":422,"placeholder":"blur","blurDataURL":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAIAAAAPE8H1AAAACXBIWXMAABJ0AAASdAHeZh94AAAANElEQVR4nGPQN9DPzMx8+vQpAxcPq4uLC5Rla2v74cMHBjFxUWNj46VLlzL4+HgXFRUBWQDB7hKjRFD0BQAAAABJRU5ErkJggg=="}]]}],"\n",["$","$L20","1709",{"id":"检查-workQueue-情况","children":["检查 workQueue 情况"]}],"\n",["$","p","1713",{"children":["用上了",["$","code","1710",{"children":["fastq"]}],"之后情况变成了定时向 queue 中 push 要抓取的 feed。这是检查 queue 长度(任务完成 / 堆积情况)就显得很重要了。受到",["$","code","1711",{"children":["--heapsnapshot-signal"]}],"启发。绑定信号 handler,在接收到信号时 log 队列长度。Demo 实测",["$","code","1712",{"children":["concurrency"]}],"设置在 500 的情况下,默认 40 秒请求 timeout。一轮 queue 清空约用时 3 分钟。"]}],"\n",["$","$L15","1714",{"id":"总结感受","children":["总结感受"]}],"\n",["$","p","1715",{"children":["heapsnapshot 是分析内存占用的利器。但是网上的资料还是比较少,google 的官方文档也也没有讲清楚一些细节。这么走下来好像很轻松,但是不太熟悉这样的分析,实际上花了很长时间才定位出问题。必须要感谢 tg 群友的提点。"]}],"\n",["$","p","1717",{"children":["最后上一幅","$L24","的资源占用图。"]}],"\n",["$","p","1719",{"children":[["$","$La",null,{"className":"m-img","id":"$undefined","alt":"memory-graph.png","style":"$undefined","loading":"lazy","src":"https://vip2.loli.io/2023/03/08/mPBCsE8S5MIcfWX.png","width":482,"height":330,"placeholder":"blur","blurDataURL":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAADCAIAAADUVFKvAAAACXBIWXMAABJ0AAASdAHeZh94AAAAO0lEQVR4nAEwAM//ADRTW2+HjjxZYQ83P8LKzQCSpauqusCSpasPICOGjI8A1t3gzdPX2uDjyMvN2dvcGvQaraweHZcAAAAASUVORK5CYII="}]]}],"\n",["$","p","1720",{"children":["看到这一个阶梯,总算觉得时间没有白费。"]}],"\n",["$","$L1b","1721",{"id":"未来展望","children":["未来展望"]}],"\n",["$","p","1724",{"children":["可能会考虑别的 schedule 的方法而不是统一在一个时间内抓取全部 feed。bot 开始的时候设计就是多个用户订阅同一个 feed 不会多次请求。这当然限制了功能,比如说每个抓取间隔是全局的而不是每个 feed 可调节的。","$L25","则是将",["$","code","1723",{"children":["(feed_id,user_id)"]}],"作为一个超键。提供了更丰富的功能,但是也导致会对多用户订阅同一个 feed 时会发多个请求。"]}],"\n"]}] 16:["$","a",null,{"href":"https://github.com/fengkx/NodeRSSBot","children":["NodeRSSBot"],"target":"_blank","rel":"noopener noreferrer external nofollow"}] 17:["$","a",null,{"href":"https://t.me/NodeRSS_bot","children":["@NodeRSS_bot"],"target":"_blank","rel":"noopener noreferrer external nofollow"}] 18:["$","a",null,{"href":"https://m.do.co/c/5d4b9ede7012","children":["digitalocean"],"target":"_blank","rel":"noopener noreferrer external nofollow"}] 19:["$","a",null,{"href":"https://github.com/fengkx/NodeRSSBot/blob/master/source/utils/fetch.ts","children":["抓取进程"],"target":"_blank","rel":"noopener noreferrer external nofollow"}] 1a:["$","a",null,{"href":"https://github.com/sindresorhus/got","children":["got"],"target":"_blank","rel":"noopener noreferrer external nofollow"}] 1c:["$","a",null,{"href":"https://developers.google.com/web/tools/chrome-devtools/memory-problems/heap-snapshots?hl=zh-cn#comparison_%E8%A7%86%E5%9B%BE","children":["Google 的官方文档"],"target":"_blank","rel":"noopener noreferrer external nofollow"}] 1d:["$","a",null,{"href":"https://www.bitdegree.org/learn/chrome-memory-tab","children":["这篇文章"],"target":"_blank","rel":"noopener noreferrer external nofollow"}] 1e:["$","a",null,{"href":"https://github.com/nodejs/node/pull/27133","children":["–heapsnapshot-signal"],"target":"_blank","rel":"noopener noreferrer external nofollow"}] 1f:["$","a",null,{"href":"https://github.com/fengkx/NodeRSSBot/blob/4d1ebd1d212a132b16f9f843dbe5a8bfa89a251b/source/utils/fetch.ts#L39","children":["res"],"target":"_blank","rel":"noopener noreferrer external nofollow"}] 21:["$","a",null,{"href":"https://github.com/tuananh/camaro","children":["camaro"],"target":"_blank","rel":"noopener noreferrer external nofollow"}] 22:["$","a",null,{"href":"https://github.com/fengkx/NodeRSSBot/blob/4d1ebd1d212a132b16f9f843dbe5a8bfa89a251b/source/utils/fetch.ts#L96","children":["代码"],"target":"_blank","rel":"noopener noreferrer external nofollow"}] 23:["$","a",null,{"href":"https://github.com/mcollina/fastq","children":["fastq"],"target":"_blank","rel":"noopener noreferrer external nofollow"}] 24:["$","a",null,{"href":"https://m.do.co/c/5d4b9ede7012","children":["digitalocean"],"target":"_blank","rel":"noopener noreferrer external nofollow"}] 25:["$","a",null,{"href":"https://miniflux.app","children":["Miniflux"],"target":"_blank","rel":"noopener noreferrer external nofollow"}]