Какие утечки памяти вызывают обработчики лямбда-событий?

В Java, когда оператор «==» используется для сравнения двух объектов, он проверяет, ссылаются ли объекты на одно и то же место в памяти. Другими словами, он проверяет, являются ли имена двух объектов в основном ссылками на одно и то же место в памяти.

Класс Java String фактически переопределяет реализацию equals () по умолчанию в классе Object и переопределяет этот метод, чтобы он проверял только значения строк, а не их местоположения в памяти. Это означает, что если вы вызываете метод equals () для сравнения двух объектов String, то, пока действительная последовательность символов равна, оба объекта считаются равными.

Оператор == проверяет, являются ли две строки точно одним и тем же объектом.

Метод .equals() проверяет, имеют ли две строки одно и то же значение.

1
задан mike 19 January 2019 в 00:54
поделиться

1 ответ

Отказ от ответственности : Я не могу гарантировать, что это 100% правда - ваш вопрос достаточно глубокий, и я могу ошибиться.

1122 Тем не менее, я надеюсь, что это даст вам некоторые мысли или указания.

Давайте рассмотрим этот вопрос в соответствии с CLR организацией памяти:

Локальные переменные метода и параметры метода хранятся в фрейме стека методов в памяти (за исключением того, что они объявлены с ключевым словом ref). [ 1124]

Стек хранит типы значений и ссылки на переменные ссылочного типа, которые указывают на объекты в куче.

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

За исключением случаев, когда локальные переменные были захвачены тем или иным образом, это также относится к работе компилятора , вы можете прочитать об этом на сайте Джона Скита:

http: // jonskeet.uk/csharp/csharp2/delegates.html#captured.variables

Версия 1 : метод OnSomeEvent является членом MyClass и будет захвачен [114 ] до тех пор, пока делегаты, ссылающиеся на этот метод, не будут удалены из события. Таким образом, экземпляр MyClass, созданный в конструкторе, помещенный в кучу и содержащий этот метод, не будет собран GC до тех пор, пока ссылка на его метод не будет удалена из события.

Компилятор компилирует лямбду особым образом, пожалуйста, прочитайте Пример реализации абзац полностью:

https://github.com/dotnet/csharplang/ blob / master / spec / conversions.md # anonymous-function-Conversions

Версия 4 : 2 предоставленные мною ссылки лямбда-импульса будут скомпилированы для метода MyClass, который будет зафиксирован экземпляром SomeClass, как в версии 1

версии 2 : я не знаю нюансов о том, как будут компилироваться локальные методы, но это должно быть таким же, как в версии 4 (и, следовательно, версии 1 ).

Версия 3 : Все локальные переменные будут захвачены интересным способом.

У вас также есть «объект x», поэтому будет создан сгенерированный компилятором класс, который будет содержать открытое поле public object x; и метод, который будет переведен из вашей лямбды (см. пример реализации абзац). [ 1135]

Итак, я думаю, что в версии 1,2,4 будут внутренне одинаковыми: MyClass будет содержать метод, который будет использоваться в качестве обработчика событий.

В версии 3 будет создан сгенерированный компилятором класс, в котором будут храниться ваша локальная переменная и метод, переведенные из lamdba.

Любой экземпляр любого класса не будет собираться GC, пока у события SomeClass не будет свой метод в списке вызовов.

0
ответ дан TheGreatCornholio 19 January 2019 в 00:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: