百科问答小站 logo
百科问答小站 font logo



C# 中如何有效地释放内存? 第1页

  

user avatar   geelaw 网友的相关建议: 
      

看来题主的问题很多啊。

1、值类型、引用类型、对象的位置

值类型的对象可以存在于托管堆(譬如,当它被装箱后,或者被匿名委托捕获了)或者栈上。引用类型的对象只能存在于托管堆上,引用类型的引用可以存在于托管堆(譬如被匿名委托捕获了)或栈上。

2、栈上的释放

如果一个栈上存储的对象超过了作用域,则它被释放。

3、托管堆上的释放

托管堆上的对象可能永远都不被释放(直到程序结束),因为 GC 的意义是模拟一个内存无限的环境,只要当前内存还够用,GC 可以永远不执行垃圾清理任务。当内存不够的时候,托管堆上的不可达的东西将会有机会被调用 Finalizer 后,被释放占用的空间。

不可达可以如下定义:如果对象 A 的某个字段引用了对象 B,或者 A(作为一个引用类型变量)引用了 B,或者委托 A 捕获了 B,则建立 A 到 B 的边。如果从某个栈上的东西或静态成员到 X 有一条路,则 X 可达。不是可达的是不可达的。

4、关于题主提到了把引用设为 null

首先,如果 X 只有一个引用,你把它所引用的改为 null 之后,X 是不可达。但是不可达不一定会被垃圾收集,这时你可以使用 GC.Collect 来强迫收集,为了确保收集效果,你可以多次调用。

第二种情况,除了你“掌控”的 X 的某个引用外,还有别的地方在引用 X,那你很可能无法强迫 X 被收集,否则为了保持一致性,其他引用 X 的必须都被撤销对 X 的引用,但是这样做可以破坏其他地方的一致性,导致整个程序坏掉。对此,一种策略是在某些 applicable 的地方使用 WeakReference。

5、Dispose

Dispose 是为了释放非托管资源准备的。譬如有一个文件类 File,底层实现是保存一个 IntPtr 作为文件的句柄,因为 File 对象释放不确定,所以我们让 File 实现 IDisposable,Dispose 方法将会关闭这个文件并让这个 File 对象处在不可用状态。也就是说,Dispose 之后 File 对象不再持有这个文件的访问权,但是 File 对象本身不一定被 finalize 或收集。


user avatar   Ivony 网友的相关建议: 
      

如果你不信任GC,你就不应该用托管对象,进而C#这种BCL中99.9%的类型是引用类型的语言都不应该用。

如果你信任GC,就别管这些破事儿。

最后,如果你连int怎么回收都不知道,应当重新温习基础课程。




  

相关话题

  「刷脸支付」靠谱吗,现在发展得怎么样了? 
  如果你现在是一个IT毕业生,你最想去国内的哪个城市或者具体的哪个公司发展,为什么? 
  java中,堆的运行速度为什么比栈慢? 
  这种电视是不是就叫伪4k? 
  C# 中如何有效地释放内存? 
  C#中关于List<T>和HashSet<T>应用的效率问题? 
  为什么技术领域很多人有“连这种简单的都不懂吗”的风气? 
  C#中的引用类型在堆栈(内存)中是怎么工作的? 
  IT 和网络技术发展正日益消弭距离的障碍,这种趋势是否会减慢甚至停止城市化的进程,或渐渐消融现有城市? 
  有人号称编程零基础学C#4天,用记事本1分钟写个计算器,而且信誓旦旦,这是怎么回事? 

前一个讨论
健康的资产负债率在什么范围?
下一个讨论
每天我们平均会花 1/3 时间在床垫上,但是为什么我们会隔两年换一部新手机,却可能10年也不会换一次床垫?





© 2024-11-09 - tinynew.org. All Rights Reserved.
© 2024-11-09 - tinynew.org. 保留所有权利