百科问答小站 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怎么回收都不知道,应当重新温习基础课程。




  

相关话题

  既然在语言层面上 Java 要落后于 C#,那为何国内 Java 架构到处都是? 
  用 Lazarus 做 GUI 程序合适吗? 
  C#能分配内存连续的引用类型数组吗? 
  java转C#的学习路线? 
  C#有哪些有名的依赖注入的框架? 
  技术牛人流动性大,应该如何管理才能降低离职率? 
  为什么在微软三月份就发布公告和更新的情况下两个月后仍有很多人中了「永恒之蓝」? 
  .Net 为什么不为 Dictionary 提供 IEqualityComparer 的默认实现? 
  C#异步方法返回Task的意义是什么?完整的TAP代码是什么结构? 
  个人信息保护法通过,将于 11 月起施行,它会给我们的生活带来什么改变? 

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





© 2025-02-20 - tinynew.org. All Rights Reserved.
© 2025-02-20 - tinynew.org. 保留所有权利