LINUX.ORG.RU

А как сборщик мусора обращается с анонимными объектами?

 ,


0

3

Например, я допустим напишу,

;(function(){
  var request = new XMLHttpRequest
  request.open("GET", "foo")
  request.onreadystatechange = function(){
    if(request.readyState == 4 && request.status == 200) alert("foo")
  request.send(null)
  }
})()

Утверждается, что сборщик стартует от root. Я так понимаю, что от какого то глобального объекта, или чего-то в этом роде.

У нас что получается. Объект функции отработал, и создал замыкание. В этом замыкании создана ссылка на экземпляр XMLHttpRequest. но на само замыкание никаких внешних ссылок нет. Значит, все это должно быть уничтожено. А что если они будут уничтожены, прежде, чем придет ответ от сервера? Как же тогда отработает коллбек?



Последнее исправление: hfucker (всего исправлений: 1)

Так а разве экземпляр XMLHttpRequest не будет создан тогда, когда сработает замыкание? С какого перепугу ему сразу то создаваться без вызова функции?

anonymous
()
Ответ на: комментарий от anonymous

Так функция вызывается сразу, это анонимная функция, которая создается, и тут же вызывается. Как только она будет вызвана, код внутри нее отработает, и XMLHttpRequest будет создан.

hfucker
() автор топика
Ответ на: комментарий от hfucker

Имплементация где-то хранит список всех активных XMLHttpRequest. Ей же надо где-то брать этот объект, когда придёт ответ по сети.

vzzo ★★★
()

Где, по-твоему, хранится коллбэк и почему ты думаешь, что он не удержит твоё замыкание?

Примерно то же самое с console.log: можно спокойно течь из-за того, что оно удерживает референс на объекты.

x3al ★★★★★
()
Ответ на: комментарий от hfucker

а, ты про другую вообще функцию. Тогда не, не удалится. Он в замыкании ссылки сохранит на этот реквест. Либо же просто не будет вызван этот колбек, потому что не будет существовать объект.

Хз. Нужно смотреть как это в JS сделано

Вот пример на lua, например, рабочий

connect - метод асинхронный

function make_connect( )
    local client = tcp("192.168.1.1:12234");
    client.connect( "on_connect", function( ) print("Connected!") end )
end
.....
make_connect( ) 

не будет работать, потому что connect асинхронный и при выходе из make_connect клиент будет уже дохл. а вот так

function make_connect( )
    local client = tcp("192.168.1.1:12234");
    client.connect( "on_connect", function( cl ) print("Connected!") end, client )
end
.....
make_connect( ) 

он будет работать и коллектор вычистит client уже после того, как отработает сигнал.

anonymous
()
Ответ на: комментарий от x3al

Коллбек хранится в памяти. Но ведь коллбек это не ссылка, а ссылка на этот коллбек есть только из экземпляра XMLHttpRequest, на который в свою очередь ссылается идентификатор «request» изнутри замыкания, на которое внешних ссылок нет.

Или ты хочешь сказать, что замыкания вообще не уничтожаются?

hfucker
() автор топика
Ответ на: комментарий от hfucker

Внутри конкретных реализаций JS сидит евентлуп, который и хранит ссылки на xhr до тех пор как он отработал.

PolarFox ★★★★★
()

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

anonymous
()
Ответ на: комментарий от x3al

то же самое с console.log: можно спокойно течь из-за того, что оно удерживает референс на объекты.

Кстати, я че то не понял, о чем ты говоришь. Как console.log может удерживать референсы и становится причиной утечки? Это функция, которая просто вызывается.

hfucker
() автор топика
Ответ на: комментарий от hfucker

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

x3al ★★★★★
()
Ответ на: комментарий от x3al

Твоя информация противоречит здравому смыслу. Вызов функции вообще не может тратить память. И вызов console.log(data), как и вызов любой другой функции, не создает ничего в памяти, и не может создавать по определению.

hfucker
() автор топика
Ответ на: комментарий от x3al

Хотя, может, конечно, если представляет из себя что-то вроде этого

object = {
 storage: [],
 method: function(arg){this.storage.push(arg)}
}
но для того чтобы что-то вывести на консоль, едва ли это нужно.

hfucker
() автор топика
Ответ на: комментарий от hfucker

Мне лень с тобой спорить, поскольку ты говоришь о какой-то идеализированной модели языка вместо того, что встречается на практике.

http://www.ibm.com/developerworks/library/wa-jsmemory/index.html#N1013E

И даже http://info.meteor.com/blog/an-interesting-kind-of-javascript-memory-leak

x3al ★★★★★
()
Ответ на: комментарий от hfucker

И вызов console.log(data), как и вызов любой другой функции, не создает ничего в памяти, и не может создавать по определению.

А где же консоль будет хранить сообщения, которые в ней показаны? Особенно если консоль, как, например, в Firefox, позволяет, например, нажать на выведенный в неё объект и посмотреть его свойства?

proud_anon ★★★★★
()

Сборщик мусора стартует от корневых ссылок. Это как минимум все глобальные объекты и все объекты на стеке. На анонимные объекты как правило есть ссылка на стеке в момент сборки. Хотя в данном случае объект не собирается по другой причине.

KblCb ★★★★★
()
Ответ на: комментарий от hfucker

Давно заметил, что именно шизофреники чаще всех прочих любят применять дебильное словосочетание «здравый смысл».

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.