Вызывает ли рекурсивный вызов setTimeout утечку памяти в цепочке замыканий? - PullRequest
0 голосов
/ 09 июля 2019

У меня есть следующий сценарий:

let func = () => {
  //...
  let id = setTimeout(() => {
    console.trace();
    clearTimeout(id);
    func();
  }, 2000);
}

func();

Если мы, например, запустим следующий код в консоли Chrome, мы получим следующую трассировку стека

console.trace
(anonymous) @ VM89644:4
setTimeout (async)
func @ VM89644:3
(anonymous) @ VM89644:6
setTimeout (async)
func @ VM89644:3
(anonymous) @ VM89644:6
setTimeout (async)
func @ VM89644:3
(anonymous) @ VM89644:6
setTimeout (async)
func @ VM89644:3
(anonymous) @ VM89644:6
setTimeout (async)
func @ VM89644:3
(anonymous) @ VM89644:6
setTimeout (async)
func @ VM89644:3
(anonymous) @ VM89644:6
...
...
...

, которая увеличивается с каждой итерацией.В конце концов он достигает максимальной точки (я думаю, что после 35 итераций), когда цепочка кажется перестает расти, но мне интересно, если это просто Chrome просто не отображает ее.Что именно происходит?

1 Ответ

1 голос
/ 09 июля 2019

Вызывает ли рекурсивный вызов setTimeout утечку памяти замкнутой цепочки?

Нет.После каждого срабатывания таймера подсистема таймера в браузере освобождает свою ссылку на функцию таймера, которая, в свою очередь, освобождает свою ссылку на среду, в которой он был создан, позволяя им обоим восстановиться.

который увеличивается на каждой итерации.В конце концов он достигает максимальной точки (я думаю, что после 35 итераций), когда цепочка, кажется, перестает расти, но мне интересно, просто Chrome просто не отображает ее.Что именно происходит?

Это стандартное управление памятью, все очищается в соответствии с эвристикой движка JavaScript для управления памятью, которая не всегда очищает все заранее.Я подозреваю, что если вы неоднократно нажимали кнопку «Собирать мусор» в devtools (на вкладке «Память»), вы заметили бы, что она возвращается почти к базовой линии.

Одна вещь, которая может помешать возврату к почти базовой линии, этоИзящные асинхронные трассировки стека V8 .Они объявляются как «нулевые затраты», но, конечно, это не может быть полностью истинно, потому что они должны отслеживать информацию асинхронного стека (даже если только в виде строки).

...