1

Я пытаюсь определить, поможет ли этот шаблон минимизировать сборку мусора в моей Javascript-игре.Функция самозапускания + закрытие для улучшения зависания из-за сбора мусора

У меня есть функция я называю в моей основной цикл игры, определенный что-то вроде этого:

my.object.prototype.method = function(some_object) { 
    var a,b,c,d,e,f,j,k; 

    // initialize variables  
    // do stuff to some_object based on variables... 

    return some_object; 
} 

Переменные в конечном итоге ссылки на объекты в другом месте в коде (или числовые значения).

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

Будет ли рефакторинг на функцию самозапуска, которая хранит переменные в замыкании, заставляет переменные повторно использовать, а не перераспределять для каждого вызова функции? Будет ли это иметь заметное влияние на GC?

my.object.prototype.method = (function() { 
    var a,b,c,d,e,f,j,k; 

    return function(some_object) { 
     // initialize variables 
     // do stuff to some_object based on variables... 
     // set variables to undefined 

     return some_object; 
    } 
})(); 

Примечание, они не являются объектами, которые выделяются в способе; просто ссылки на другие объекты или примитивы.

Я пробовал, и, похоже, что-то ухудшилось. Кажется, что GC выполняется гораздо чаще и имеет одинаковую отдачу от производительности каждый раз (и собирает около того же объема памяти, что и раньше).

Есть ли что-то, что мне не хватает здесь, что может привести к снижению производительности? Будет ли это вести себя так, как ожидалось (распределяя переменные один раз и повторно используя их, даже не собирая их?) Или что-то еще происходит?

+0

Зачем устанавливать переменные 'undefiend'? Я бы подумал, что это сделает память подходящей для сбора. Если значения переменных всегда одного типа и являются примитивами, я думаю, что память будет использоваться повторно, если вы просто замените значения по мере необходимости. Трудно сказать, хотя. Может быть, что-то еще в вашем коде делает выделение. – user2736012

+0

Настройка на неопределенное, чтобы я не сохранял ссылку на что-либо ненужное. Например, один из объектов, которые я ссылаюсь, представляет собой матрицу, содержащую текущее преобразование объекта для этого фрейма. Если я позвоню только один раз, я не хочу, чтобы он предотвращал GC этой матрицы; цель здесь состоит в том, чтобы избежать создания сотен локально видимых варов на кадр, которые должны быть GC'd позже. Хотя, думая об этом, я теперь задаюсь вопросом, как косвенные эти ссылки сравниваются, например, с примитивным объектом. –

+0

Не уверен, что вы подразумеваете под «примитивным объектом». В JavaScript это оксюморон. Но поскольку ваши переменные, похоже, содержат ссылки на объекты, тогда да, если вы установите для переменной значение «undefined», будет собрана ссылка, как и объект, если это была последняя ссылка на него. Таким образом, вы не предотвращаете сбор мусора, делая это. Теперь переменная имеет совершенно другое значение ... значение 'undefined', которое, как я полагаю, является единственным значением, имеющим одно место в памяти. Трудно настроить мелочи на небольшом уровне. Но если вы можете повторно использовать объекты, это должно помочь. – user2736012

ответ

1

Я не уверен в этом, но это может помочь, если вы очистите объекты в коде с помощью функции очистки. Я нашел интересную статью, которая могла бы помочь вам больше: https://www.scirra.com/blog/76/how-to-write-low-garbage-real-time-javascript

В частности, я хотел бы посмотреть на это:

You can actually re-cycle an existing object (providing it has no prototype chain) by 
deleting all of its properties, restoring it to an empty object like {}. For this you 
can use the cr.wipe(obj) function, defined as: 

    // remove all own properties on obj, 
    effectively reverting it to a new object 
    cr.wipe = function (obj) 
    { 
    for (var p in obj) 
    { 
     if (obj.hasOwnProperty(p)) 
      delete obj[p]; 
     } 
    }; 

Это или установить их равными ничего, если используется массив, установите его длину до 0, таким образом позже это не нужно будет собирать мусор, когда вы переназначаете его

+0

Кажется забавным, что код выполняет проверку '.hasOwnProperty()' перед операцией 'delete'. – user2736012

+0

Мы на самом деле используем что-то подобное в другом месте, и, похоже, это помогло. Здесь, однако, это просто ссылки на другие объекты (или числа). Мы не хотим уничтожать ссылку на объект, просто не хотим создавать тысячи ссылок, которые выпадают из сферы действия, и их необходимо очистить. –