Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 25.02.2015, 23:38
Новичок на форуме
Отправить личное сообщение для JSInteres Посмотреть профиль Найти все сообщения от JSInteres
 
Регистрация: 25.02.2015
Сообщений: 2

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

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 не подразумевает работу с какими либо ещё переменными.
Ответить с цитированием
  #2 (permalink)  
Старый 26.02.2015, 10:54
Профессор
Отправить личное сообщение для tsigel Посмотреть профиль Найти все сообщения от tsigel
 
Регистрация: 12.12.2012
Сообщений: 1,398

Сообщение от 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".

Последний раз редактировалось tsigel, 26.02.2015 в 10:57.
Ответить с цитированием
  #3 (permalink)  
Старый 26.02.2015, 11:27
Аватар для Erolast
Профессор
Отправить личное сообщение для Erolast Посмотреть профиль Найти все сообщения от Erolast
 
Регистрация: 24.09.2013
Сообщений: 1,436

var theItem = null;
var replaceItem = function () {
    theItem = {
        longStr: new Array(1000000).join('*'),
        someMethod: function () {
            console.log(someMessage);
        }
    };
};
setInterval(replaceItem, 1000);
Ответить с цитированием
  #4 (permalink)  
Старый 26.02.2015, 22:10
Новичок на форуме
Отправить личное сообщение для JSInteres Посмотреть профиль Найти все сообщения от JSInteres
 
Регистрация: 25.02.2015
Сообщений: 2

Спасибо, с бульевой переменной впринципе вариант. Просто я думал что возможно есть способ как то явно выгружать объект.
Ответить с цитированием
  #5 (permalink)  
Старый 27.02.2015, 08:32
Аватар для Erolast
Профессор
Отправить личное сообщение для Erolast Посмотреть профиль Найти все сообщения от Erolast
 
Регистрация: 24.09.2013
Сообщений: 1,436

Зачем вообще 3-8 строки? Они никак поведение кода не меняют (за исключением добавления утечки).
Ответить с цитированием
  #6 (permalink)  
Старый 27.02.2015, 08:50
Профессор
Отправить личное сообщение для tsigel Посмотреть профиль Найти все сообщения от tsigel
 
Регистрация: 12.12.2012
Сообщений: 1,398

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

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

Вообще если возникает такая ситуация возможно стоит поискать другое архитектурное решение чтобы более тонко контролировать функции созданные в замыкании и иметь возможность убивать переменные в них.
Ответить с цитированием
  #7 (permalink)  
Старый 27.02.2015, 18:19
Аватар для Erolast
Профессор
Отправить личное сообщение для Erolast Посмотреть профиль Найти все сообщения от Erolast
 
Регистрация: 24.09.2013
Сообщений: 1,436

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

Последний раз редактировалось Erolast, 27.02.2015 в 18:24.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как удалить из памяти весь XML документ? EisBerg Events/DOM/Window 1 03.04.2010 14:45
Как лучше решить проблему с парсингом строки alexKniaz Общие вопросы Javascript 2 05.11.2009 16:22
Утечки памяти: как сделать ? Draeden Events/DOM/Window 10 30.08.2009 18:16
Как лучше сделать глобальный массив skyfish AJAX и COMET 4 17.02.2009 18:05
Помогите решить задачу vkg Общие вопросы Javascript 1 20.02.2008 11:59