在 List.ForEach 中声明 Func<> 会导致内存泄漏并增加进程内存吗?
Does declaring Func<> in List.ForEach causing memory leak and increase process memory?
我知道我不应该在 foreach
中声明 Func<>
,但我想知道这段 C# 代码是否会增加进程内存并导致内存泄漏?
class Foo {
int[] FooA = { 1, 2, 3, 4 };
string result = "";
void myMethod() {
FooA.ToList().ForEach(a => {
Func<int, string> myFunc = myFuncVar => $"Value: {myFuncVar}\n";
result += myFunc(a);
});
MessageBox.Show(result);
}
}
使用 sharplab;
这样的反汇编工具很有帮助
// trim
internal class Foo
{
[Serializable]
[CompilerGenerated]
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static Func<int, string> <>9__2_1;
internal string <myMethod>b__2_1(int myFuncVar)
{
return string.Format("Value: {0}\n", myFuncVar);
}
}
private int[] FooA;
private string result;
private void myMethod()
{
Enumerable.ToList(FooA).ForEach(new Action<int>(<myMethod>b__2_0));
}
public Foo()
{
int[] array = new int[4];
RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
FooA = array;
result = "";
base..ctor();
}
[CompilerGenerated]
private void <myMethod>b__2_0(int a)
{
Func<int, string> func = <>c.<>9__2_1 ?? (<>c.<>9__2_1 = new Func<int, string>(<>c.<>9.<myMethod>b__2_1));
result += func(a);
}
}
// trim
您可以看到您的 lambda (myFuncVar => $"Value: {myFuncVar}\n";
) 已提升为单例实例 (<>c.<>9
) 上的方法 (<myMethod>b__2_1
)。使用 Func 委托的延迟初始化静态缓存 (<>c.<>9__2_1
).
所以不,至少在这种情况下,这里实际上没有进行每次迭代分配。
编译器可以证明您的 lambda 不需要引用局部变量,也不需要任何其他实例字段。即使您为该 lambda 分配的变量具有本地作用域和生命周期,lambda 本身也可以提升为静态生命周期。类似于字符串文字分配给变量的方式,但字符串对象具有静态生命周期。
我知道我不应该在 foreach
中声明 Func<>
,但我想知道这段 C# 代码是否会增加进程内存并导致内存泄漏?
class Foo {
int[] FooA = { 1, 2, 3, 4 };
string result = "";
void myMethod() {
FooA.ToList().ForEach(a => {
Func<int, string> myFunc = myFuncVar => $"Value: {myFuncVar}\n";
result += myFunc(a);
});
MessageBox.Show(result);
}
}
使用 sharplab;
这样的反汇编工具很有帮助// trim
internal class Foo
{
[Serializable]
[CompilerGenerated]
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static Func<int, string> <>9__2_1;
internal string <myMethod>b__2_1(int myFuncVar)
{
return string.Format("Value: {0}\n", myFuncVar);
}
}
private int[] FooA;
private string result;
private void myMethod()
{
Enumerable.ToList(FooA).ForEach(new Action<int>(<myMethod>b__2_0));
}
public Foo()
{
int[] array = new int[4];
RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
FooA = array;
result = "";
base..ctor();
}
[CompilerGenerated]
private void <myMethod>b__2_0(int a)
{
Func<int, string> func = <>c.<>9__2_1 ?? (<>c.<>9__2_1 = new Func<int, string>(<>c.<>9.<myMethod>b__2_1));
result += func(a);
}
}
// trim
您可以看到您的 lambda (myFuncVar => $"Value: {myFuncVar}\n";
) 已提升为单例实例 (<>c.<>9
) 上的方法 (<myMethod>b__2_1
)。使用 Func 委托的延迟初始化静态缓存 (<>c.<>9__2_1
).
所以不,至少在这种情况下,这里实际上没有进行每次迭代分配。
编译器可以证明您的 lambda 不需要引用局部变量,也不需要任何其他实例字段。即使您为该 lambda 分配的变量具有本地作用域和生命周期,lambda 本身也可以提升为静态生命周期。类似于字符串文字分配给变量的方式,但字符串对象具有静态生命周期。