#类,对象,引用
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;
}
}