memory leaks
столкнулся с утечкой. устранить удалось, но почему возникает - понимания не возникло. может кто-нибудь внятно разъяснить? спасибо
упрощенный код : getInfo( options, argument ){ let __this = this; this.readSQLInfo(options, argument).then(( result )=>{ //--- result большой массив с данными return __this.sendResult( options,argument, result.slice() ) }).catch( error => { ....... }); } sendResult( objectQuery,options,resultInfo ){ options.message = resultInfo; //--- большой массив ................. ................. options.message = null; // --- если закоментарить строку то будет утечка return true; } ///--- opt и arg не глобальные переменные, они имеют блоковую видимость let opt = { a:0,b:10 } let arg = { c:0,d:10 } this.getInfo( opt,arg ) |
Мб this.readSQLInfo запоминает.
|
непонятно.
все функции успешно отрабатывают, никаких "ожидающих", а соответственно их замыканий не остается. Кто там и что запоминает - должен все что запомнил освободить, по причине - отсутствия ссылок на что либо. единственное подозрение - это две разные области видимости (options и resultInfo) (хотя и они потом уничтожаются) и перекрестная ссылка между ними options.message = resultInfo причем вот так вот: let opt = { a:0,b:10 } let arg = { c:0,d:10 } this.getInfo( opt,arg ) arg = null opt = null т.е. явный отказ от декларированных переменных - не помогает. только вариант как в начале поста нигде в литературе не могу найти подобного. хотелось бы разобраться |
Советую поискать на ютубе - "профилирование java script".
Думаю это очень полезно знать и уметь. |
да я уже запрофилировался. нашел утечку именно профилированием. с инструментами разобрался. Я просто не понимаю - почему!!!
|
fxobject, покажи полный код - можно будет о чём-то говорить.
Есть вариант что это ленивый gc и он просто не успевает всё чистить, проверить это можно запустив код в ноде о флагом разрешающим запускать gc руками. Но я всё же склоняюсь к тому, что один из методов через которые ты прокидываешь эти твои opt и arg где-то умудряется сохранить ссылку. Может кэширование какое или мемоизация... |
вот упрощенная давнишняя версия но точно с такой же утечкой:
function onConnect( wsClient ) { wsClient.on('message', function (message) { let options = JSON.parse( message ); let sendResult = function( resultInfo,statusInfo = true ){ options.status = statusInfo; if( resultInfo !== undefined ) options.message = resultInfo; else options.message = {} wsClient.send( JSON.stringify( options )); return true; } let info = [] //--- большой массив данных sendResult( info ,false); return будет наблюдаться утечка |
не ленивый gc....... c нажатием кнопки чтения данных наблюдается резкое увеличение потребляемой памяти. с ключами пробовал, это не сборщик мусора.
кэширование какое или мемоизация - понимаю о чем, не использую. |
Замыкание функционального выражения на каждый вызов "wsClient.on ( ...." это накладная операция.
Из кода непонятно зачем на каждый вызов создавать уникальную для этого вызова функцию вместо использования одной на все вызовы "wsClient.on ( ....". |
это старая версия функции и приведена только в учебных целях.
|
Часовой пояс GMT +3, время: 03:24. |