Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Как лучше решить задачу с утечкой памяти? (https://javascript.ru/forum/misc/53971-kak-luchshe-reshit-zadachu-s-utechkojj-pamyati.html)

JSInteres 25.02.2015 23:38

Как лучше решить задачу с утечкой памяти?
 
Всем привет,

var theItem = null;
var replaceItem = function () {
    var priorItem = theItem;
    var writeToLog = function () {
        if (priorItem) {
            console.log("hi");
        }
    };
    theItem = {
        longStr: new Array(1000000).join('*'),
        someMethod: function () {
            console.log(someMessage);
        }
    };
};
setInterval(replaceItem, 1000);


Есть вот такая вот задачка, c утечкой памяти в методе writeToLog. Каждый раз создается большой объект и ссылка на него сохраняется в определении функции writeToLog , сборщик мусора не удаляет объект, так как на него сохраняется ссылка. Итак далее по нарастающей. Как лучше решить данную задачу не передавая priorItem функции writeToLog в качестве параметра? Так как writeToLog не подразумевает работу с какими либо ещё переменными.

tsigel 26.02.2015 10:54

Цитата:

Сообщение от JSInteres
Есть вот такая вот задачка, c утечкой памяти в методе writeToLog. Каждый раз создается большой объект и ссылка на него сохраняется в определении функции writeToLog , сборщик мусора не удаляет объект, так как на него сохраняется ссылка. Итак далее по нарастающей. Как лучше решить данную задачу не передавая priorItem функции writeToLog в качестве параметра? Так как writeToLog не подразумевает работу с какими либо ещё переменными.

var theItem = null;
var replaceItem = function () {
    var priorItem = !!theItem;
    var writeToLog = function () {
        if (priorItem) {
            console.log("hi");
        }
    };
    theItem = {
        longStr: new Array(1000000).join('*'),
        someMethod: function () {
            console.log(someMessage);
        }
    };
};
setInterval(replaceItem, 1000);


Все зависит от целей вашей задачи, в данном конкретном случае достаточно "priorItem" сделать булиновой переменной в зависимости от значения "theItem".

Erolast 26.02.2015 11:27

var theItem = null;
var replaceItem = function () {
    theItem = {
        longStr: new Array(1000000).join('*'),
        someMethod: function () {
            console.log(someMessage);
        }
    };
};
setInterval(replaceItem, 1000);

JSInteres 26.02.2015 22:10

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

Erolast 27.02.2015 08:32

Зачем вообще 3-8 строки? Они никак поведение кода не меняют (за исключением добавления утечки).

tsigel 27.02.2015 08:50

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

JSInteres,
Конечно можно и по другому, тут весь вопрос в том как вы используете функцию в замыкании. Если она используется одноразово (имеется в виду конкретный экземпляр функции созданный в конкретном замыкании), то в конце функции можно просто обнулить priorItem (priorItem = null) и утечки не будет, но при повторном вызове условие не пройдет.

Вообще если возникает такая ситуация возможно стоит поискать другое архитектурное решение чтобы более тонко контролировать функции созданные в замыкании и иметь возможность убивать переменные в них.

Erolast 27.02.2015 18:19

Цитата:

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

Вообще если возникает такая ситуация возможно стоит поискать другое архитектурное решение
+


Часовой пояс GMT +3, время: 12:11.