Под что выделится новая память в компилированной лямбде?
Допустим есть метод. Под что в данном примере выделится память?
class C
{
public void Method()
{
Task.Run(() => { });
}
}
В Release компилятор сделает следующую структуру:
public class C
{
[Serializable]
[CompilerGenerated]
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static Action <>9__0_0;
internal void <M>b__0_0()
{
}
}
public void M()
{
Task.Run(<>c.<>9__0_0 ?? (<>c.<>9__0_0 = new Action(<>c.<>9.<M>b__0_0)));
}
}
Получается, что в классе <>c создается поле <>c <>9 = new <>c() для того, чтобы обратиться к методу <M>b__0_0. Я так полагаю доп. память выделяется только <>9.
Ведь если не использовать лямбу:
public class C
{
public void M()
{
Task.Run(new Action(A));
}
void A() {}
}
То компилируется это в то же самое и память соответственно выделяется только под new Action() (в первом случае у нас еще и инициализация поля <>9).
Ответы (1 шт):
Очевидно же, лямбда изолируется в самостоятельном объекте, если не считать нестатические члены, то в нем ничего нет, поэтому расход памяти будет равен минимальному размеру объекта в памяти, 24 байта для x64 и 12 байт для x86, насколько я помню. Память под две статические ссылки - 16 или 8 байт соответственно будет выделена при запуске приложения.
Объект, как видно, будет создан однократно на всё время работы приложения. Поэтому расход процессорного времени и памяти на создание объекта будет произведен однократно, а впоследствии объект будет переиспользован.
Есть кстати неплохая статья на Хабре на эту тему.