精通C#--对象的生命周期

#类,对象,引用

public class Car
{
	public int CurrentSpeed{get; set;}
	public string PetName{get; set;}
	public Car(){}
	public Car(string name, int speed)
	{
		PetName = name;
		CurrentSpeed = speed;
	}
	
	public override string ToString()
	{
		return string.Format("{0} is going {1} MPH", PetName, CurrentSpeed);
	}
}

1.应用程序根的作用
根就是一个存储位置,保存着对托管堆上一个对象的引用。
根可属于下面任何一个类别:
全局对象的引用
静态对象/静态字段的引用
应用程序代码库中局部对象的引用
传递进一个方法的对象参数的引用
等待被终结的对象的引用
任何引用对象的CPU寄存器

2.对象的代
第0代:从没有被标记为回收的新分配的对象。
第1代:在上一次垃圾回收中没有被回收的对象【被标记为回收,但因为已获取了足够的堆空间而没有被删除】。
第2代:在一次以上的垃圾回收后仍然没有被回收的对象。

3.System.GC

AddMemoryPressure(...)
RemoveMemoryPressure(...)
Collect(...)
CollectionCount(...)
GetGeneration(...)
GetTotalMemory(...)
MaxGeneration
SuppressFinalize(...)
WaitForPendingFinalizers(...)


static void Main()
{
	Console.WriteLine("***xxx***\n");
	Console.WriteLine("Estimated bytes on heap:{0}", GC.GetTotalMemory(false));
	Console.WriteLine("This OS has {0} object generations.\n", (GC.MaxGeneration + 1));
	Car refToMyCar = new Car("Zippy", 100);
	Console.WriteLine(refToMyCar.ToString());

	Console.WriteLine("\nGeneration of refToMyCar is :{0}", GC.GetGeneration(refToMyCar));

	object[] tonsOfObjects = new object[50000];
	for(int i = 0; i < 50000; i++)
		tonsOfObjects[i] = new object();

	GC.Collect(0, GCCollectionMode.Forced);
	GC.WaitForPendingFinalizers();
	Console.WriteLine("Generation of refToMyCar is:{0}", GC.GetGeneration(refToMyCar));

	if(tonsOfObjects[9000] != null)
	{
		Console.WriteLine("Generation of tonsOfObjects[9000] is {0}", GC.GetGeneration(tonsOfObjects[9000]));
	}
	else
	{
		Console.WriteLine("tonsOfObjects[9000] is no longer alive.");
	}

	Console.WriteLine();
}

4.构建可终结对象

public class Object
{
	...
	// 将最终发生在一次自然的垃圾回收或GC.Collect()强制回收中。
	// 使用了非托管资源时,在释放对象时,释放关联的非托管资源
	protected virtual void Finalize();
	...
}

class MyResourceWrapper
{
	~MyResourceWrapper()
	{
		// 清除非托管资源
		
	}
}

C#编译器执行一个终结器语法时,自动在被隐式重写的Finalize方法中增加许多必须的基础代码。
在托管堆上分配对象时,运行库自动确定该对象是否提供一个自定义的Finalize。如提供,对象 被标记为可终结的,一个指向这个对象的指针被保存在终结队列的内部队列中。

5.构建可处置对象

public interface IDisposable
{
	void Dispose();
}

class MyResourceWrapper : IDisposable
{
	public void Dispose()
	{
		// 清除非托管资源
	}
}

class Program
{
	static void Main()
	{
		Console.WriteLine("***");
		MyResourceWrapper rw = new MyResourceWrapper();
		rw.Dispose();
		Console.ReadLine();
	}
}

static void Main()
{
	Console.WriteLine("***");
	// 退出using作用域时,自动调用Dispose
	using(MyResourceWrapper rw = new MyResourceWrapper())
	{
		// 使用rw对象
	}
}

6.构建可终结类型和可处置类型
将两种技术混合进同一个类。
如果 对象用户记住了调用Dispose,可以通过调用GC.SuppressFinalize通知垃圾回收器跳过终结过程。
如果 对象用户忘记了Dispose,对象最终也将被终结并有机会释放内部资源。

public class MyResourceWrapper : IDisposable
{
	~MyResourceWrapper()
	{
		// 清除内部的非托管资源
		// 不调用任何托管对象的Dispose
	}

	public void Dispose()
	{
		// 在这里清除非托管资源
		// 在其它包含的可处置对象上调用Dispose
		
		// 如果调用了Dispose()就不需要终结,因此跳过终结
		// 通知CLR在对象被回收时不再需调用析构函数
		GC.SuppressFinalize(this);
	}
}

7.正确的处置模式

class MyResourceWrapper : IDisposable
{
	// 用来判断Dispose是否已被调用
	private bool disposed = false;
	public void Dispose()
	{
		// 调用辅助方法
		// 指定true表示对象用户触发了清理过程
		CleanUp(true);
		// 跳过终结
		GC.SuppressFinalize(this);
	}

	private void CleanUp(bool disposing)
	{
		// 保证还没被处置
		if(!this.disposed)
		{
			if(disposing)
			{
				// 释放托管的资源
			}

			// 清理非托管的资源 
		}

		disposed = true;
	}

	~MyResourceWrapper()
	{
		// 
		CleanUp(false);
	}
}

##延迟对象实例化

class Song
{
	public string Artist{get; set;}
	public string TrackName{get; set;}
	public double TraceLength{get; set;}
}

class AllTracks
{
	private Song[] allSongs = new Song[10000];
	public AllTracks()
	{
		Console.WriteLine("Filling up the songs!");
	}
}

class MediaPlayer
{
	public void Play(){...}
	public void Pause(){...}
	public void Stop(){...}
	private AllTracks allSongs = new AllTracks();
	public AllTracks GetAllTracks()
	{
		return allSongs;
	}
}

Lazy<>,该类所定义的数据在代码库实际使用它之前是不会被创建的。

class MediaPlayer
{
	...
	private Lazy<AllTracks> allSongs = new Lazy<AllTracks>();
	// 在访问Lazy<T>::Value时,才创建T
	public AllTracks GetAllTracks()
	{
		return allSongs.Value;
	}
}

class MediaPlayer
{
	...
	private Lazy<AllTracks> allSongs = new Lazy<AllTracks>
	(
		()=>
		{
			Console.WriteLine("Creating AllTracks object!");
			return new AllTracks();
		}
	);

	public AllTracks GetAllTracks()
	{
		return allSongs.Value;
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

raindayinrain

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值