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

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

问题描述

我在C#中的计时器,它执行了一些code里面的方法。里面的code我用几个临时的对象。


  1. 如果我有像美孚O =新的Foo(); 的方法中,这是否意味着每个计时器滴答声的时候,我创建一个新的对象和新的引用,该对象?


  2. 如果我有字符串富=空然后我只是把东西foo的时间,难道是上面一样?


  3. 请问垃圾收集器永远删除对象和基准或物体的持续创建,并留在记忆?


  4. 如果我只是声明富O; ,而不是它指向任何情况下,这不就是处置时,该方法结束


  5. 如果我想确保一切都被删除,什么是做的最好的方式:


    • 在方法内部using语句

    • 将在最后调用Dispose方法

    • 通过将富O; 计时器的方法外,也将让分配 O =新的Foo()内,所以后来的指针对象被删除的方法结束后,垃圾收集器会删除对象。



解决方案

  

1。如果我有像美孚O =新的Foo();该方法中,是否
  意味着每次计时器滴答,
  我创建一个新的对象和新的
  引用该对象?



  

2。如果我有串富=空,然后我只是把一些时间在富,
  是它与上述相同


如果你问,如果该行为是那么同样是肯定的。


  

3.Does垃圾收集器有史以来删除对象和参考或
  对象不断创建和
  留在记忆?


后的参考文献被认为是未使用的那些对象使用的存储器是最肯定收集


  

4,如果我只是声明富O;而不是指向任何情况下,是不是
  处置时,该方法结束?


没有,因为没有对象创建那么有没有对象收集(配置不正确的字)。


  

5。如果我想确保一切都被删除,什么是最好的方式
  做


如果该对象的类实现的IDisposable ,那么你一定要贪婪地叫的Dispose 尽快。在使用关键字使得这个更容易,因为它要求的Dispose 自动异常安全的方式。

除此之外,真的没有别的需要,除了做停止使用的对象。如果引用是局部变量然后当它超出范围,将有资格领取。 1 如果它是一个类级别的变量,那么你可能需要分配来它,使之符合之前的含类是符合条件的。


1 这是技术上不正确(或至少有点误导)。一个对象可以有资格领取它超出范围之前很久。 CLR的优化,当它检测到的引用不再用于收集内存。在极端的情况下,CLR可以收集甚至在它的方法仍在执行的对象!

更新:

下面是一个演示了GC将收集的对象,即使他们可能仍然在范围内的例子。你必须编译发布版本并运行此调试器之外。

 静态无效的主要(字串[] args)
{
    Console.WriteLine(分配之前);
    VAR博=新BigObject();
    Console.WriteLine(经过分配);
    bo.SomeMethod();
    到Console.ReadLine();
    //对象是技术上在此范围内,这意味着它仍然必须扎根。
}私有类BigObject
{
    私人字节[] = LotsOfMemory新字节[Int32.MaxValue / 4];    公共BigObject()
    {
        Console.WriteLine(BigObject());
    }    〜BigObject()
    {
        Console.WriteLine(〜BigObject());
    }    公共无效的someMethod()
    {
        Console.WriteLine(开始的someMethod);
        所以GC.Collect();
        GC.WaitForPendingFinalizers();
        Console.WriteLine(结束的someMethod);
    }
}

在我的机器上,而的someMethod 仍执行终结运行!

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

  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. If I have string foo = null and then I just put something temporal in foo, is it the same as above?

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

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

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

    • 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.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?

Yes.

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.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.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.If I want to ensure that everything is deleted, what is the best way of doing it

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.

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.


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!

Update:

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");
    }
}

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

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

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