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, время: 02:02. |