百科问答小站 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类的职位呀? 
  作为非计算机专业的学生,觉得 C 语言远比其他语言易于上手,正常吗? 
  C#中如何通过字段名(类型为字典)反射获取该字典的所有值? 
  用 Lazarus 做 GUI 程序合适吗? 
  为什么在微软三月份就发布公告和更新的情况下两个月后仍有很多人中了「永恒之蓝」? 
  为什么 C# 发明 13 年之后微软才推出编译为本地代码的功能? 
  为什么一个简单的闭包,C#要设计得如此巨大? 
  军事战争中网络攻防主要有哪些打击手段?与地面战争会存在哪些结合? 
  C# 如何在调用控件时做到 Thread-safe(线程安全)? 
  一个即将步入大学对编程感兴趣的学生,3 年能将 Java 学到什么程度,应怎样合理分配这 3 年? 

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





© 2025-03-26 - tinynew.org. All Rights Reserved.
© 2025-03-26 - tinynew.org. 保留所有权利