2013-03-01 2 views
1

Это всего лишь несколько строк из официальных документов node.js.Является ли этот код nodejs круглой ссылкой?

client.on('data', function(data) { 
    console.log(data.toString()); 
    client.end(); 
}); 

Я думаю, что клиентский объект имеет ссылку на обратный вызов, обратный вызов имеет ссылку на замыкание на объект клиента. Это верно? Если да, то почему это рекомендуется?

+0

«клиент» в обратном вызове ссылается на исходный клиент из-за области, поэтому он не может ссылаться на какой-либо другой «клиент», если вы не переопределите его. Это не вызывает каких-либо проблем, поэтому их можно использовать безопасно. Единственный другой способ - передать в качестве аргумента в качестве аргумента (у вас нет контроля над тем, что передает инфраструктура) или определить клиента в другой области, такой как «окно», что может вызвать больше проблем и не имеет никаких улучшений. –

ответ

2

Да, это круговая ссылка, но это не утечка памяти. Учитывая только этот фрагмент кода, у вас есть только небольшой график нескольких объектов, но да, если client доступен из вашей основной программы, все эти объекты никогда не будут иметь права на сбор мусора. Однако, если вы должны были установить client = null;, график объектов, включая объект client, и функцию анонимного обработчика событий будет недоступен из основной программы и, следовательно, будет иметь право на сбор мусора и, таким образом, A-OK.

Этот шаблон сам по себе не является утечкой памяти. Если бы вы создавали клиентов в цикле и сохраняли ссылку на все из них в массиве или объекте без кода, чтобы когда-либо удалять устаревших клиентов, тогда да, это будет утечка памяти.

+0

Спасибо. Могут быть более сложные циклические ссылки. Могу ли я сказать, что два объекта, которые ссылаются друг на друга, прямые или косвенные, будут собирать мусор V8? Только когда один из них ссылается на третий объект, произойдет утечка памяти? –

+0

Это правильно. Если весь большой граф объектов становится недоступным из исполняемой части кода, весь граф имеет право на сбор мусора. Наиболее типичные шаблоны кода, такие как выше, не будут вызывать утечки. Будьте бдительны при использовании объектов или массивов в виде кешей, карт, коллекций и т. Д., Поскольку они являются вероятными кандидатами на утечки ошибок add-but-never-remove. –

1

Это правильно. Событие Emitters в node.js хранит своих слушателей в частной собственности _listeners. Функция обработчика использует client как закрытую переменную, что не является абсолютно необходимым, потому что все обработчики вызываются с эмиттером событий в качестве ссылки this.

Однако, используя this вместо client не меняет тот факт, что client находится в крышке, это только намекает V8 разыменовать это от закрытия, потому что она не используется.

Даже если он был использован из замыкания, V8 имеет достаточную логику для обработки таких циркулярных ссылок и освобождения их из памяти должным образом.

+1

Спасибо. Поэтому нам не стоит беспокоиться о круговых ссылках в этом шаблоне? –

Смежные вопросы