CLR实用特征--自动内存管理(垃圾收集)
20.2垃圾收集算法
20.3垃圾收集与调试
一旦对象变为不可达的对象,它就成为垃圾收集器的目标---不保证对象在方法的生存期中自始自终的存活。
20.4使用终结操作来释放本地资源
20.5对托管资源使用终结操作
20.6那些事件会导致Finalize方法的调用
1. 第0代对象。
2. 代码显式调用System.GC的静态方法Collect。
3. Windows报告内存不足。
4. CLR卸载应用程序域。
5. CLR被关闭
20.7终结操作内部揭秘
终结操作现象:我们创建一个对象,当该对象被执行垃圾收集时,垃圾收集器就会调用它的Finalize方法。
详细参见书上的三个图。
20.8释放模式:强制对象清理资源
20.9使用实现了释放模式的类型
20.10C#的Using语句
20.11一个有趣的依赖问题
见书
20.12人工监视和控制对象的生存期
为了监视和控制对象的生存期,可以调用GCHandle的静态方法Alloc。
该方法的参数:需要监视的对象的引用、GCHandleType
public enum GCHandleType {
Weak=0,//用于监视对象
WeakTrackResurrection=1,//用于监视对象
Normal=2,//用于控制对象的生存期
Pinned = 3//用于控制对象的生存期
}
20.13对象复苏
20.14对象的代
1.CLR支持3个代:第0代,第1代,第2代。
2.第0代对象就是新构建的对象。
3.代是垃圾收集器的一种机制,它存在的唯一目的就是提供应用程序的性能。
20.15使用本地资源的其他垃圾收集特性
现象:
有时,本地资源会消耗大量内存,但包装该资源的托管对象只占用了非常少的内存。(如位图)
GC提供的两个静态方法:
AddMemoryPressure(Int64 bytesAllocated);
RemoveMemoryPressure(Int64 bytesAllocated);
20.16预测需求较多内存的操作能否成功
现象:
实现一个算法时,使用了大量的内存。如果内存耗尽,CLR会抛出异常。我们也需要做大量工作进行恢复。
System.Runtime提供了一个MemoryFailPoint类,它在执行内存消耗巨大的算法时为我们提供了这种检测内存不足的能力。
public class SomeType {
private void SomeMethod() {
try {
using (MemoryFailPoint mfp = new MemoryFailPoint(1500)) {
//执行内存较大的算法
} }
catch(InsufficientMemoryException e){
Console.WriteLine(e);
}
}}
20.17编程控制垃圾收集器
System.GC提供了直接控制垃圾收集器的一些方法。
internal sealed class GenObj {
~GenObj() {
Console.WriteLine("In Finalize Method"); }
public static void Main() {
Console.WriteLine("Maximum generations:" + GC.MaxGeneration);
Object o = new GenObj();
//对象是新创建的,是第0代
Console.WriteLine("Gen " + GC.GetGeneration(o));//Gen 0
GC.Collect();
Console.WriteLine("Gen " + GC.GetGeneration(o));//Gen 1
GC.Collect();
Console.WriteLine("Gen " + GC.GetGeneration(o));//Gen 2
o = null;//销毁对象的强引用
Console.WriteLine("Collecting Gen 0");
GC.Collect(0);//收集第0代对象
GC.WaitForPendingFinalizers();//不调用Finalize方法
Console.WriteLine("Collecting Gens 0,and 1");
GC.Collect(1);//收集第0代对象
GC.WaitForPendingFinalizers();//不调用Finalize方法
Console.WriteLine("Collecting Gens 0,1,and 2");
GC.Collect(2);//收集第0代对象
GC.WaitForPendingFinalizers();//不调用Finalize方法
Console.ReadLine();
}
}
Maximum generations:2
Gen 0
Gen 1
Gen 2
Collecting Gen 0
Collecting Gens 0,and 1
Collecting Gens 0,1,and 2
In Finalize Method
20.18与垃圾收集器性能相关的其他一些话题
1.免同步的多线程分配。
2.可扩展并行收集。
3. 并发收集。
4.大尺寸对象。
20.19监视垃圾收集器
GC提供了两个静态方法,可以查看某个指定的代已经执行了多少次垃圾收集操作:
Int64 GetTotalMemory(Boolean forceFullCollection);
Int32 CollectionCount(Int32 generation);