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




  

相关话题

  视频文件在硬盘里放时间久了清晰度会下降吗?为什么? 
  c#入门书籍有推荐吗? 
  C# 中关于static的使用? 
  C# ConcurrentQueue 怎么长时间循环取任务? 
  内存管理中,进程涉及会换出和换入的问题? 
  IT 行业的工资是否虚高? 
  C#中ExpressionTree需要学习吗?如何学习? 
  Build 2015上微软宣布Windows 10支持Objective-C与Java编写的应用,这对C#与Windows自身有什么长远影响? 
  c#启动有什么好的优化技巧? 
  为什么C# MVC5,DateTime属性默认的JSON解析值的格式为“/Date()/”? 

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





© 2024-05-18 - tinynew.org. All Rights Reserved.
© 2024-05-18 - tinynew.org. 保留所有权利