Закрытие утечки памяти - PullRequest
3 голосов
/ 09 марта 2011

Меня интересует возможность утечек памяти (ненужные ссылки) утечек памяти в языках с мусором

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

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

Ответы [ 4 ]

3 голосов
/ 09 марта 2011

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

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

1 голос
/ 27 января 2013

Во многих языках, если создано несколько делегатов, которые закрывают некоторые переменные в данной области, каждый делегат, закрывающий любую из этих переменных, будет закрывать все из них.Например:

Action blah(Dictionary<string, int> dict, List<string> list)
{
  int i;
  list.ForEach( (st) => if (dict.Contains(st)) i++; );
  return () => Console.WriteLine("The value was {0}", i);
}

Этот метод создаст двух делегатов.Первым нужны переменные dict и i, и они будут отменены до выхода из функции.Второму нужно только i, но вызывающий может удерживать его бесконечно долго.Пока вызывающая сторона сохраняет делегат, возвращенный этим методом, переданный словарь не будет собираемым.

Компилятор мог бы избежать этой проблемы, создав два замыкания, одно из которых содержалоdict и int[1], а другой из которых только что держал int[1];оба замыкания будут содержать ссылку на один и тот же int[1], сохраняя тем самым требуемую семантику.На практике, однако, дополнительные расходы связаны с лишними захватами.

1 голос
/ 09 марта 2011

Это не совсем то, что вы имеете в виду, но сборщик мусора в Internet Explorer <7 раньше не мог собирать переменные с циклическими ссылками. Это не имеет ничего общего с замыканиями как таковыми, но оказывается, что замыкания в javascript могут легко создавать циклические ссылки. </p>

Я думаю, что такой шаблон подойдет

function foo() {
    var div = document.getElementById('mydiv');
    div.onclick = bar;

    function bar() {
        div.style.opacity = 0.5;
    }
}

Теперь, что бы вы ни делали, функция bar ссылается на переменную div и в то же время присваивается свойству div.

Как следствие, при использовании замыканий в IE необходимо было уделять особое внимание предотвращению утечек памяти .

0 голосов
/ 09 марта 2011

Переменные в замыкании не «перехватываются», а просто по-прежнему ссылаются, GC не собирается собирать их до тех пор, пока не будет выпущена ссылка.Когда приложение завершает работу, все незавершенные замыкания будут отменены, а все связанные ресурсы освобождены.Нет утечки памяти, поскольку все выделенные ресурсы освобождены.

...