在 C# 中释放内存的正确方法是什么 [英] What is the correct way to free memory in C#

查看:82
本文介绍了在 C# 中释放内存的正确方法是什么的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 C# 中有一个计时器,它在它的方法中执行一些代码.在代码中,我使用了几个临时对象.

I have a timer in C# which executes some code inside it's method. Inside the code I'm using several temporary objects.

  1. 如果我在方法内部有类似 Foo o = new Foo(); 的东西,这是否意味着每次计时器滴答作响时,我都在创建一个新对象和一个新对象?引用那个对象?

  1. If I have something like Foo o = new Foo(); inside the method, does that mean that each time the timer ticks, I'm creating a new object and a new reference to that object?

如果我有 string foo = null 然后我只是在 foo 中放了一些时间,它和上面的一样吗?

If I have string foo = null and then I just put something temporal in foo, is it the same as above?

垃圾收集器是否曾经删除过对象,而引用或对象会不断地创建并留在内存中?

Does the garbage collector ever delete the object and the reference or objects are continually created and stay in memory?

如果我只是声明 Foo o; 而没有将它指向任何实例,那不是在方法结束时被处理了吗?

If I just declare Foo o; and not point it to any instance, isn't that disposed when the method ends?

如果我想确保所有内容都被删除,最好的方法是什么:

If I want to ensure that everything is deleted, what is the best way of doing it:

  • 在方法中使用 using 语句
  • 最后调用 dispose 方法
  • 通过将 Foo o; 放在定时器的方法之外,然后将赋值 o = new Foo() 放在里面,然后在调用之后删除指向该对象的指针方法结束,垃圾收集器将删除该对象.
  • with the using statement inside the method
  • by calling dispose method at the end
  • by putting Foo o; outside the timer's method and just make the assignment o = new Foo() inside, so then the pointer to the object is deleted after the method ends, the garbage collector will delete the object.

推荐答案

1.如果我有类似 Foo o = new Foo();在方法内部,这样做意味着每次计时器滴答作响,我正在创建一个新对象和一个新对象引用那个对象?

1.If I have something like Foo o = new Foo(); inside the method, does that mean that each time the timer ticks, I'm creating a new object and a new reference to that object?

是的.

2.如果我有字符串 foo = null 然后我只是在 foo 中放了一些时间,和上面一样吗?

2.If I have string foo = null and then I just put something temporal in foo, is it the same as above?

如果您问行为是否相同,则是.

If you are asking if the behavior is the same then yes.

3.垃圾收集器是否曾经删除过对象和引用或对象不断地被创建和留在记忆中?

3.Does the garbage collector ever delete the object and the reference or objects are continually created and stay in memory?

这些对象使用的内存肯定会在引用被视为未使用之后被回收.

The memory used by those objects is most certainly collected after the references are deemed to be unused.

4.如果我只是声明 Foo o;并且不指向任何实例,是不是方法结束时处理?

4.If I just declare Foo o; and not point it to any instance, isn't that disposed when the method ends?

不,因为没有创建对象,所以没有对象要收集(处理不是正确的词).

No, since no object was created then there is no object to collect (dispose is not the right word).

5.如果我想确保所有内容都被删除,最好的方法是什么这样做

5.If I want to ensure that everything is deleted, what is the best way of doing it

如果对象的类实现了IDisposable,那么你肯定想尽快调用Dispose.using 关键字使这更容易,因为它以异常安全的方式自动调用 Dispose.

If the object's class implements IDisposable then you certainly want to greedily call Dispose as soon as possible. The using keyword makes this easier because it calls Dispose automatically in an exception-safe way.

除此之外,除了停止使用该对象外,您无需执行任何其他操作.如果引用是局部变量,那么当它超出范围时,它将符合收集条件.1 如果它是类级变量,则您可能需要分配 null在包含类符合条件之前,使其符合条件.

Other than that there really is nothing else you need to do except to stop using the object. If the reference is a local variable then when it goes out of scope it will be eligible for collection.1 If it is a class level variable then you may need to assign null to it to make it eligible before the containing class is eligible.

1这在技术上是不正确的(或者至少有点误导).一个对象可以在超出范围之前很久就符合收集条件.CLR 经过优化,可在检测到不再使用引用时收集内存.在极端情况下,CLR 甚至可以在其方法之一仍在执行时收集对象!

1This is technically incorrect (or at least a little misleading). An object can be eligible for collection long before it goes out of scope. The CLR is optimized to collect memory when it detects that a reference is no longer used. In extreme cases the CLR can collect an object even while one of its methods is still executing!

更新:

这是一个示例,演示了 GC 将收集对象,即使它们可能仍在范围内.您必须编译发布版本并在调试器之外运行它.

Here is an example that demonstrates that the GC will collect objects even though they may still be in-scope. You have to compile a Release build and run this outside of the debugger.

static void Main(string[] args)
{
    Console.WriteLine("Before allocation");
    var bo = new BigObject();
    Console.WriteLine("After allocation");
    bo.SomeMethod();
    Console.ReadLine();
    // The object is technically in-scope here which means it must still be rooted.
}

private class BigObject
{
    private byte[] LotsOfMemory = new byte[Int32.MaxValue / 4];

    public BigObject()
    {
        Console.WriteLine("BigObject()");
    }

    ~BigObject()
    {
        Console.WriteLine("~BigObject()");
    }

    public void SomeMethod()
    {
        Console.WriteLine("Begin SomeMethod");
        GC.Collect();
        GC.WaitForPendingFinalizers();
        Console.WriteLine("End SomeMethod");
    }
}

在我的机器上,终结器在 SomeMethod 仍在执行时运行!

On my machine the finalizer is run while SomeMethod is still executing!

这篇关于在 C# 中释放内存的正确方法是什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆