在C#中,将对象设置为null以释放内存是必要的吗?

4

6
那并不能释放内存,它只是覆盖了一个指针。而且这个问题之前已经被问过很多次了。 - user395760
1
@delnan:我仍然认为这是一个合理的问题,因为在COM的旧时代,你必须这样做才能释放引用计数。 - n8wrl
6个回答

7
不会立即执行,如果您正确编写代码通常是不必要的。如果您有一个实现IDisposable的资源,请调用其上的Dispose()方法,甚至更好的方法是将其放在using(...)块中——这样可以更快地释放所需资源。如果您在同一作用域中有几个大对象不是COM对象或没有实现某种形式的处理机制,则执行以下操作:
someObject = null;
GC.Collect();

也许会有所帮助,但最好重构您的代码,以便您不会陷入这种情况。

如果您在对象超出范围之前执行此操作,则完全是多余的,并且会使事情变得更糟。如果您在finalizer中将内容设置为null,则更是如此。例如,永远不要这样做:

public void aFunction() {
    SomeThing anObject = new SomeThing();
    // ...
    anObject = null;
}

也不是这样:

public ~MyClass() {
    this.Something = null; // WRONG!
    this.SomethingElse.Dispose(); // DANGEROUS!
    this.SomeObject.Notify("I got finalized!"); // ALSO DANGEROUS!
}

为了完整起见,您需要执行以下操作:

Marshal.ReleaseComObject(someObj);

释放COM对象。

1
此外,在方法底部将这些变量设置为null被认为是一种去优化。你实际上正在与JITter和GC作斗争。https://dev59.com/-nE85IYBdhLWcg3wgDvd#2742867 - Mike Hofer

2

将引用设置为 null 不会删除对象使用的内存,但最终会被垃圾回收。

假设您有两个对象 A 和 B,其中 A 引用 B。

如果不再存在对 A 的任何引用,则 A 和 B 都将被垃圾回收。清除 A 对 B 的引用是没有意义的。

但是,如果 A 是长寿命对象而且不再需要 B,那么清除对 B 的引用可能是值得的,这样可以使其被垃圾回收。

在 asp.net 的上下文中,您主要处理短寿命对象,因此通常不是问题。


2

将对象引用设置为null不会释放内存,但它会允许垃圾回收器在稍后的某个时间释放内存。

只要您持有对象的引用,它就不会被垃圾回收,但在正常的ASP.NET代码中,您很少需要考虑它,因为大多数对象只在请求期间被引用。当请求被垃圾回收时,大多数在其中创建的对象也将自动垃圾回收。

这个“软规则”的主要例外是静态或共享资源,如果保留引用可能导致它们在许多请求中存在并随着时间的推移而增加。换句话说,避免使用静态变量,您默认情况下大部分都会没问题。


1
不,它不是。如果对象不是可释放的,垃圾回收器会很好地处理它。此外,您并没有释放内存,而是修改变量。

1
在垃圾回收的环境中,你不需要“释放”内存。首先阅读this

1

我没有为非常高流量的网站或Web应用工作过。但是我有我的业务2业务门户和运行在Web上的实践管理系统,每天有大约1000-3000个访问量和并发用户。为此,我在所有层中都使用静态对象。考虑到公共静态变量,它给我带来了一些好处:

  1. 我需要较少的对象来创建,因为单个静态对象被共享。
  2. 代码更清晰,以便后期维护。
  3. 静态构造函数只调用一次。

对象的清理我交给GC处理,因为GC会检查是否有任何孤立的对象,并自动释放其空间。

据我所知,对于你的问题:

  1. 设置为null将重置指针而不是释放内存。
  2. 在正常代码中释放内存不是强制性的,但是从内存中删除所有不必要的对象是一个好习惯,这样可以释放内存,使您的应用程序适当地工作而没有任何问题。

Web应用程序中的静态对象可能非常危险,因为它们是共享的,并且可以被多个线程同时访问。 - John Saunders

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接