.NET框架下的自动内存管理

王子VS公主86

王子VS公主86

2016-01-29 12:30

.NET框架下的自动内存管理,.NET框架下的自动内存管理
C#使用的自动内存管理,使用开发者从繁重的手工分配、释放内存的操作解放出来。内存的自动管理是由垃圾回收器来执行。一个对象使用内存的生命周期是这样的:
  当对象被创建时,它便分配了一定的内存,当构造器中的代码开始运行时,这个对象就“活”了。
当这个对象或者是它的任何一部分在可以预计的将来已经没有任何作用时,这个对象将不会再使用,它就应当被销毁。
  一旦这个对象符合了对销毁的条件,在一定的时间后,这个对象的销毁器就将被执行,一般情况下,除非被显示地重写,这个销毁器只能运行一次。
  一旦销毁器被运行,那么这个对象以及它任何一部分都不可能在以后的运行中使用,这甚至包括正在运行的销毁器。这时这个对象将被认为是不可见的,它所占的资源将会被回收。
  最后由垃圾回收器释放这个对象所占的资源。
  垃圾回收器控制着这些对象的使用信息并利用这些信息控制内存,比如内存哪里创建了一个新对象,什么时候重新创建对象以及什么时候将这个对象释放。
  像其它的语言一样,C#假定确实存在这样一个垃圾回收器,而且这个垃圾回收器可以管理很大范围的内存。比如,C#并不要求销毁器一事实上要执行,也不要求对象一旦无用则马上回收。
  当然垃圾回收器的行为也是可以被控制的,这个控制的方法来自于System.GC类。这个类可以请求回收、销毁器运行等操作。
  下面是一个例子。
class A
{
~A() {
Console.WriteLine("Destruct instance of A");
}
}
class B
{
object ref;
public B(object o) {
ref = o;
}
~B() {
Console.WriteLine("Destruct instance of B");
}
}
class TMest
{
static void Main() {
B b = new B(new A());

b = null;
GC.Collect();
GC.WaitForPendingFinalizers();
}
}
  上面的程序创建了类A与类B的一个实例,当变量b被赋于null值时,A与B均符合了垃圾回收器的回收要求。此时就没有任何代码能够访问它们了。
  执行的结果,下面两种情况都有可能:
Destruct instance of A
Destruct instance of B

Destruct instance of B
Destruct instance of A
  因为上面的程序的并没有限制这两个对象被回收的顺序。
  在某些敏感的条件下,有关区分“销毁”与“回收”操作条件的定义是非常重要的:
class A
{
~A() {
Console.WriteLine("Destruct instance of A");
}
public void F() {
Console.WriteLine("A.F");
TMest.RefA = this;
}
}
class B
{
public A Ref;
~B() {
Console.WriteLine("Destruct instance of B");
Ref.F();
}
}
class TMest
{
public static A RefA;
public static B RefB;
static void Main() {
RefB = new B();
RefA = new A();
RefB.Ref = RefA;
RefB = null;
RefA = null;
// A and B now eligible for destruction
GC.Collect();
GC.WaitForPendingFinalizers();
// B now eligible for collection, but A is not
if (RefA != null)
Console.WriteLine("RefA is not null");
}
}
  在上面的程序中,如果垃圾回收器选择先执行类B的销毁器,那么执行的结果为:
Destruct instance of A
Destruct instance of B
A.F
RefA is not null
  注意,虽然实例A并没有被使用,但是从输出的结果大家可以看到A的销毁器确实执行了,而且连A的方法F也被执行了。同时我们也注意至,一个对象销毁器的运行又可能使一个实例变得可用。在这种情况下,实例B销毁器的执行使得先前并没有调用的实例A也可以被访问了,而这一种就是引用RefA的功劳,当调用WaitForPendingFinalizers方法以后,实例B就可以被垃圾回收器回收,而此时的实例A则还不可以。
  为了区分这些行为,大家编写程序时,最好只管理当前类的销毁器,而不要采用引用其它类的实例或者静态字段。
展开更多 50%)
分享

猜你喜欢

.NET框架下的自动内存管理

电脑网络
.NET框架下的自动内存管理

.NET框架下Oracle到SQL Server迁移

Web开发
.NET框架下Oracle到SQL Server迁移

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

代码最优化.NET中的内存管理

C语言教程 C语言函数
代码最优化.NET中的内存管理

Microsoft .NET Romoting 框架简介

电脑网络
Microsoft .NET Romoting 框架简介

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

微软的远程处理框架.NET Remoting - 1

电脑网络
微软的远程处理框架.NET Remoting - 1

VB.NET如何在没有.NET框架的机器上运行

电脑网络
VB.NET如何在没有.NET框架的机器上运行

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

五彩缤纷建网页(3)色彩的象征

五彩缤纷建网页(3)色彩的象征

小偷程序原理和简单示例

小偷程序原理和简单示例
下拉加载更多内容 ↓