国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

Node.js SetTimeout 引起的內(nèi)存泄露問(wèn)題

開(kāi)發(fā) 前端
clearTimeout 中支持傳入 id 刪除定時(shí)器,而之前只支持傳入定時(shí)器對(duì)象。一切看起來(lái)沒(méi)問(wèn)題,但是實(shí)現(xiàn)這個(gè)特性的時(shí)候,忘了一種場(chǎng)景,那就是如果用戶沒(méi)有執(zhí)行 clearTimeout,而是定時(shí)器正常觸發(fā),因?yàn)樵诙〞r(shí)器正常觸發(fā)的邏輯中沒(méi)有刪除映射關(guān)系,從而導(dǎo)致了內(nèi)存泄露。

這是之前寫(xiě)的一篇文章,分享一下避免大家踩坑。

定時(shí)器回調(diào)通常會(huì)通過(guò)閉包持有外部的對(duì)象,比如下面的例子。

function demo() {
 const dummy = {}
 setTimeout(() => {
      dummy;
   }, 10000)
}

demo();

demo 執(zhí)行完后,demo 函數(shù)里的 dummy 對(duì)象是不會(huì)釋放的,因?yàn)樗€被 setTimeout 引用著,如果執(zhí)行很多次 demo 的話,就會(huì)導(dǎo)致大量的內(nèi)存無(wú)法被釋放,直到執(zhí)行完 setTimeout,這通常不是什么問(wèn)題,除非 dummy 對(duì)象非常大。

但是如果是 setInterval 的話,情況就不一樣了。

function demo() {
 const dummy = {}
 setInterval(() => {
      dummy;
   }, 10000)
}

demo();

上面的代碼會(huì)導(dǎo)致 dummy 永遠(yuǎn)不會(huì)被釋放,當(dāng)然這個(gè)例子很直接,大家并不會(huì)寫(xiě)出這樣的代碼,但是有時(shí)候代碼復(fù)雜的時(shí)候,就不好說(shuō)了,比如之前幫助業(yè)務(wù)排查問(wèn)題的時(shí)候經(jīng)常發(fā)現(xiàn) setInterval 導(dǎo)致的內(nèi)存泄露問(wèn)題,使用場(chǎng)景基本如下。

class Demo { 
    timer = null
    start() {
        this.timer = setInterval(() => {
            this;
        }, 10000)
    }
    stop() {
    // 通常會(huì)漏了這一句
    // clearInterval(this.timer);
    }
}

const demo = new Demo();
demo.start();
demo.stop();

所以使用 setInterval 的時(shí)候需要特別注意。

setInterval 導(dǎo)致內(nèi)存泄露很好理解,但是 setTimeout 導(dǎo)致的內(nèi)存泄露并不常見(jiàn),因?yàn)?setTimeout 執(zhí)行完后,相應(yīng)的內(nèi)存都會(huì)被釋放了。下面分享一個(gè)因?yàn)?Node.js Core 導(dǎo)致的 setTimeout 內(nèi)存泄露問(wèn)題,相關(guān) issue 可以參考這里。復(fù)現(xiàn)代碼如下。

for (i = 0; i < 500000; i++) {
   +setTimeout(() => {}, 0);
}

上面的代碼會(huì)導(dǎo)致 setTimeout 創(chuàng)建的 timer 對(duì)象無(wú)法釋放,乍一看,我們可以會(huì)被嚇到,這不就是我們平時(shí)的用法嗎?但是不用擔(dān)心,下面的例子并不會(huì)出現(xiàn)這個(gè)問(wèn)題。

for (i = 0; i < 500000; i++) {
 setTimeout(() => {}, 0);
}

仔細(xì)一看,有問(wèn)題的例子中 setTimeout 還有個(gè) + 號(hào),那么這個(gè)是做什么的呢?

這個(gè)還要說(shuō)起 setTimeout 在瀏覽器的實(shí)現(xiàn),在瀏覽器中,setTimeout 返回的是一個(gè) id,但是 Node.js 中返回的是一個(gè)對(duì)象,為了和瀏覽器兼容,Node.js 支持把返回的對(duì)象轉(zhuǎn)成 id,這個(gè) id 是定時(shí)器對(duì)應(yīng)的 async_hooks id,那么這個(gè)是怎么實(shí)現(xiàn)的呢?下面看一個(gè)例子。

const dummy = {
  [Symbol.toPrimitive]() {
   return 1
  }
};
console.log(+dummy)

上面例子會(huì)輸出 1,可以看到通過(guò) Symbol.toPrimitive 可以定義對(duì)象轉(zhuǎn)成原生類(lèi)型時(shí)的行為。下面是另一個(gè)例子。

const dummy = {
  [Symbol.toPrimitive]() {
    return "hello ";
  }
};
console.log(dummy + "world")

Node.js 正是利用這個(gè)能力實(shí)現(xiàn)了和瀏覽器的兼容,源碼如下。

Timeout.prototype[SymbolToPrimitive] = function() {
  const id = this[async_id_symbol];
  if (!this[kHasPrimitive]) {
    this[kHasPrimitive] = true;
    knownTimersById[id] = this;
  }
  return id;
};

所以一開(kāi)始那個(gè)例子中 +setTimeout 最終會(huì)執(zhí)行上面的代碼,從而拿到一個(gè) id。但是事情沒(méi)有那么簡(jiǎn)單,從上面的代碼中可以看到,除了返回一個(gè) id 外,還有另外一個(gè)邏輯,那就是把定時(shí)器對(duì)象保存到了一個(gè) map 中,其中 key 正是給用戶返回的 id,那么這個(gè)有什么用呢?看一下 clearTimeout 代碼。

function clearTimeout(timer) {
  if (typeof timer === 'number' || typeof timer === 'string') {
    const timerInstance = knownTimersById[timer];
    if (timerInstance !== undefined) {
      timerInstance._onTimeout = null;
      /*
         if (timerInstance[kHasPrimitive])
            delete knownTimersById[timerInstance[async_id_symbol]];
      */
      unenroll(timerInstance);
    }
  }
}

可以看到 clearTimeout 中支持傳入 id 刪除定時(shí)器,而之前只支持傳入定時(shí)器對(duì)象。一切看起來(lái)沒(méi)問(wèn)題,但是實(shí)現(xiàn)這個(gè)特性的時(shí)候,忘了一種場(chǎng)景,那就是如果用戶沒(méi)有執(zhí)行 clearTimeout,而是定時(shí)器正常觸發(fā),因?yàn)樵诙〞r(shí)器正常觸發(fā)的邏輯中沒(méi)有刪除映射關(guān)系,從而導(dǎo)致了內(nèi)存泄露。具體修復(fù)方案就是刪除這個(gè)映射關(guān)系就行,具體可以參考這個(gè) PR。

1. issue: https://github.com/nodejs/node/issues/53335.

2: pr: https://github.com/nodejs/node/pull/53337

責(zé)任編輯:姜華 來(lái)源: 編程雜技
相關(guān)推薦

2025-10-15 00:26:20

2023-06-30 23:25:46

HTTP模塊內(nèi)存

2013-08-07 10:07:07

Handler內(nèi)存泄露

2017-03-20 13:43:51

Node.js內(nèi)存泄漏

2017-03-19 16:40:28

漏洞Node.js內(nèi)存泄漏

2022-01-02 06:55:08

Node.js ObjectWrapAddon

2020-01-03 16:04:10

Node.js內(nèi)存泄漏

2022-06-23 06:34:56

Node.js子線程

2015-01-14 13:50:58

AndroidHandler內(nèi)存泄露

2015-03-10 10:59:18

Node.js開(kāi)發(fā)指南基礎(chǔ)介紹

2013-11-01 09:34:56

Node.js技術(shù)

2012-04-11 13:46:33

ibmdw

2021-12-25 22:29:57

Node.js 微任務(wù)處理事件循環(huán)

2020-05-29 15:33:28

Node.js框架JavaScript

2012-02-03 09:25:39

Node.js

2011-09-08 13:46:14

node.js

2011-11-01 10:30:36

Node.js

2011-09-02 14:47:48

Node

2011-09-09 14:23:13

Node.js

2012-10-24 14:56:30

IBMdw
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

97在线观看免费高清视频| 欧美日韩在线观看一区二区| 波多野结衣家庭教师视频| 国产欧美欧美| 亚洲成年人在线播放| 国产免费av高清在线| 亚洲精品中文字幕乱码三区| 成人午夜小视频| jizz内谢中国亚洲jizz| 精品欧美国产一区二区三区| 特级毛片在线| 一区二区在线看| 粉嫩av一区二区三区天美传媒| 最新亚洲视频| 久久久久免费视频| 男女羞羞视频教学| 国产日韩精品久久久| 最新二区三区av| 亚洲视频你懂的| 天堂√在线中文官网在线| 中文字幕精品一区| 久久精品国产一区二区三区日韩| 首页国产精品| 成人免费视频网站| 久久成人久久爱| 毛片精品免费在线观看| 免费国产在线视频| 国产精品99久久久久久白浆小说| 久久精品青草| 91最新在线免费观看| 蜜桃视频在线一区| 亚洲精品日韩在线| 一区二区美女| 成人有码视频在线播放| 国产成人午夜精品影院观看视频| 444亚洲人体| 伊人久久大香线蕉综合影院首页| 678五月天丁香亚洲综合网| 2018高清国产日本一道国产| 丝袜美腿亚洲色图| 国产综合视频在线观看| 亚洲午夜免费| 亚洲人午夜精品| 538在线视频| 欧美疯狂做受xxxx富婆| 中文在线www| 精品久久久久久久久中文字幕| 999精品视频在线| av亚洲精华国产精华精华| 国产精品免费看一区二区三区| 成人在线视频国产| 亚洲国产精品小视频| 色的视频在线免费看| 亚洲成人激情av| 成人黄色免费电影| 欧美国产禁国产网站cc| 国产成人无码一二三区视频| 国产超碰在线一区| www.69av| 盗摄精品av一区二区三区| 中文字幕日韩精品一区二区| 久久精品99国产精品日本| 欧美一级二级三级| 99国产精品久久久久久久成人热| 97人人做人人人难人人做| 欧洲美女日日| 国产欧美日韩精品在线观看| 日本黄色精品| 国产精品视频中文字幕91| 成人精品电影| 国产在线高清精品| 亚洲精品网址| 成人91视频| 国产欧美日本| 午夜欧美性电影| 久久99久久99| 日本大片免费看| 99国产精品一区| 亚洲熟妇av日韩熟妇在线| 91香蕉国产在线观看软件| 大地资源网在线观看免费官网| 精品一区二区成人精品| 亚洲精品第一区二区三区| 欧美a级一区二区| 国产欧美自拍视频| 久久新电视剧免费观看| 国语对白在线视频| 五月激情综合网| 成人在线免费公开观看视频| 日韩一区二区免费电影| 亚洲风情在线资源| 久久综合久中文字幕青草| 日韩中文字幕视频网| 国产精品永久免费观看| 国产精品一区亚洲| 亚洲第一综合网站| 99精品视频中文字幕| 污网站免费在线| 黑人巨大精品欧美一区二区免费| 久久电影中文字幕| 亚洲福利视频网| 北条麻妃在线一区二区免费播放| 国产精品久久久久久亚洲调教| 精品999日本| 在线观看亚洲视频啊啊啊啊| 久久精品亚洲精品国产欧美kt∨| 日本在线免费观看视频| 欧美精品在线一区二区三区| 成人在线高清| 国产精品美女呻吟| 蜜桃视频第一区免费观看| 成年人视频观看| 欧美日韩美女在线| 午夜激情在线播放| 国产精品成人av在线| 亚洲欧美视频一区二区三区| 九色自拍视频在线观看| 亚洲一区二区视频在线| 日本精品在线| 中文国产成人精品久久一| 精品一区二区三区中文字幕老牛| 国产一区二区三区av在线| 成人精品一区二区三区四区| 一本到av在线| 中文字幕成人精品久久不卡| 影音先锋日韩在线| 一本久道高清无码视频| 懂色av影视一区二区三区| 456亚洲精品成人影院| 91精品久久久久久久久| 国产91丝袜在线播放| 欧美3p视频在线观看| 久久夜色精品亚洲噜噜国产mv | 91大神xh98hx在线播放| 亚洲欧美中文日韩在线| 蜜臀久久99精品久久一区二区| 一区二区三区免费看| 亚洲成人资源在线| 亚洲一区有码| 视频一区不卡| 亚洲成av人片一区二区三区| 成人亚洲免费| 好吊色欧美一区二区三区| 国产精品高清亚洲| 香蕉久久免费电影| 欧美日韩系列| 精品久久久久久中文字幕| 国产一区二区三区视频在线| 日韩免费一区二区三区| 亚洲成av人片| 91精品短视频| 日本丰满少妇黄大片在线观看| 色综合天天狠狠| 国产一区二区三区视频在线| 亚洲国产日韩综合一区| 欧美亚洲综合网| 国产va免费精品观看精品视频| 亚洲熟妇av一区二区三区漫画| 日韩欧美综合一区| 国产精品大片| 羞羞视频在线免费看| 久久久综合av| 久久久一区二区| 激情久久一区二区| av动漫免费观看| 日韩欧美国产电影| 日韩视频三区| 黄色片视频在线观看| 国产精品美女久久久免费| 国产日韩综合av| 国产99在线| 一区国产精品| 精品第一国产综合精品aⅴ| 一本综合久久| av电影院在线看| 国产免费xxx| 日韩在线观看你懂的| 国产欧美一区二区精品秋霞影院| 欧美亚洲色图校园春色| 在线视频国产三级| 国内精品二区| 亚洲欧美成人网| 久久亚洲一区二区三区四区| 美女久久99| 麻豆视频在线观看免费| 国产在线拍揄自揄拍无码| 欧美大成色www永久网站婷| 亚洲另类中文字| 日韩午夜av| 欧美综合社区国产| 成人亚洲一区二区三区| 91精品国产高清久久久久久91裸体| 欧美一级二级在线观看| 97久久超碰国产精品| 免费一区二区三区视频导航| 国产福利在线看| 可以看毛片的网址| 国产精品激情自拍| 日韩亚洲欧美高清| 久久久久国色av免费看影院|