在下面的代码中,
private void button1_Click(object sender, EventArgs e)
{
MyForm myForm = new MyForm();
myForm.Show();
}
一般来说,myForm这个对象在button1_Click方法结束后,生命周期便结束,将会被GC清除。但是实际上myForm对应的窗口如果不按右上角“关闭按钮”是不会被GC清除的。为什么GC会对myForm“另眼相看”呢?
对C#和GC理解有限,请各位大侠出手释惑!
private void button1_Click(object sender, EventArgs e)
{
MyForm myForm = new MyForm();
myForm.Show();
}
一般来说,myForm这个对象在button1_Click方法结束后,生命周期便结束,将会被GC清除。但是实际上myForm对应的窗口如果不按右上角“关闭按钮”是不会被GC清除的。为什么GC会对myForm“另眼相看”呢?
对C#和GC理解有限,请各位大侠出手释惑!
这个 是很 容易理解的 事情 虽然C#里面不存在真实的指针 但是 new 一个对象的时候 同样可以看作是对这个对象的动态指针定义.
要知道 局部的 动态指针 是不会在函数结束后 自动消亡的.
这样 就只有等待 GC来回收了.我的理解是这样 大家共同探讨
*****************************************************************************
有空 来坐坐.我的Bloghttp://blog.csdn.net/hertcloud/
winform 背后应该关联于真实的windows窗口,可以从from.Handler属性看出
他不能被垃圾回收类似于sqlconnection 它关联于一个非托管的资源。或者说它不是纯粹的.net类。
虽然不太了解,但如果不show 退出方法后是会被回收的
show出之后是不是就进入了 另外一个相对的进程啊?这个进程消亡之前是不会被回收的(界面?)
protected override void SetVisibleCore(bool value)
{
if ((this.GetVisibleCore() != value) || (this.dialogResult != DialogResult.OK))
{//这里应该是判断Visible是否发生改变或者dialogResult是不是OK
if ((this.GetVisibleCore() == value) && (!value || this.CalledMakeVisible))
{//这里进一步的确认Visible没有发生改变(注意上面的if,其实这个分支的第一个判断就是判断dialogResult是不是OK,如果dislogResault不是OK,那么这里的this.GetVisibleCore() == value与上面的条件互斥),并且visible被设为false或者自己的CalledMakeVisible属性为true。
base.SetVisibleCore(value);
}
else
{//换言之,这里是this.GetVisibleCore()发生了改变的分支
if (value)//如果Visible被设置为true
{
this.CalledMakeVisible = true;
if (this.CalledCreateControl)
{
if (this.CalledOnLoad)
{
if (!Application.OpenFormsInternal.Contains(this))
{
Application.OpenFormsInternalAdd(this);//关键在这里,真相大白
}
}
else
{
this.CalledOnLoad = true;
this.OnLoad(EventArgs.Empty);
if (this.dialogResult != DialogResult.None)
{
value = false;
}
}
}
}
else
{
this.ResetSecurityTip(true);
}
if (!this.IsMdiChild)
{
base.SetVisibleCore(value);
if (this.formState[FormStateSWCalled] == 0)
{
UnsafeNativeMethods.SendMessage(new HandleRef(this, base.Handle), 0x18, value ? 1 : 0, 0);
}
}
else
{
if (base.IsHandleCreated)
{
this.DestroyHandle();
}
if (!value)
{
this.InvalidateMergedMenu();
base.SetState(2, false);
}
else
{
base.SetState(2, true);
this.MdiParentInternal.MdiClient.PerformLayout();
if ((this.ParentInternal != null) && this.ParentInternal.Visible)
{
base.SuspendLayout();
try
{
SafeNativeMethods.ShowWindow(new HandleRef(this, base.Handle), 5);
base.CreateControl();
if (this.WindowState == FormWindowState.Maximized)
{
this.MdiParentInternal.UpdateWindowIcon(true);
}
}
finally
{
base.ResumeLayout();
}
}
}
this.OnVisibleChanged(EventArgs.Empty);
}
if ((value && !this.IsMdiChild) && ((this.WindowState == FormWindowState.Maximized) || this.TopMost))
{
if (base.ActiveControl == null)
{
base.SelectNextControlInternal(null, true, true, true, false);
}
base.FocusActiveControlInternal();
}
}
}
}
{
if ( !value || this.CalledMakeVisible )
{
base.SetVisibleCore(value);
}
else if ( this.GetVisibleCore() != value )
{
if (value)
{
this.CalledMakeVisible = true;
if (this.CalledCreateControl && this.CalledOnLoad)
{
if (!Application.OpenFormsInternal.Contains(this))
{
Application.OpenFormsInternalAdd(this);//关键在这里,真相大白
}
}
}
}
}
{
base.SetVisibleCore(value);
}
else if ( this.GetVisibleCore() != value )
{
if (value)
{
this.CalledMakeVisible = true;
if (this.CalledCreateControl && this.CalledOnLoad)
{
if (!Application.OpenFormsInternal.Contains(this))
{
Application.OpenFormsInternalAdd(this);//关键在这里,真相大白
}
}
}
}嗯……刚提取错了……
hertcloud(·£孙子兵法£·) ( 四星(高级)) 信誉:100 2007-6-1 8:56:32 得分:0
? 如果 楼主 学习过c/c++
这个 是很 容易理解的 事情 虽然C#里面不存在真实的指针 但是 new 一个对象的时候 同样可以看作是对这个对象的动态指针定义.
要知道 局部的 动态指针 是不会在函数结束后 自动消亡的.
这样 就只有等待 GC来回收了.我的理解是这样 大家共同探讨
不信可以做个试验
form.Dispose( .. )
{
加一句
MessageBox.Show("my clear");
}
from1 f1 = new f1();
//这里不加show
看看什么情况???
Application.OpenFormsInternalAdd(this);
这句话使得myForm的指针并没有丢失,因此GC不会对myForm指向那块堆空间“下毒手”,是不是这样的?另:你贴的这些.net自己的代码是怎么看到的?
具体的操作,不仅在il层次上,还有更底层因素在里面
myForm.Show(); ------------------------------------
首先退出方法体后,确实被释放了,但释放的是指向对象的指针:myForm,而不是变量指向的内存.因为Form是引用类型的.因用类型的对象的释放并不是指指向它的指针的释放!
=======================
瞎说
Dispose 没有被执行如何释放
另:你贴的这些.net自己的代码是怎么看到的?Reflector
引用指定对象,使其从当前例程开始到调用此方法的那一刻为止均不符合进行垃圾回收的条件。
Dispose 没有被执行如何释放
-----------------------------------------
hdt(倦怠) ( ) 信誉:120 Blog 加为好友
说话太过肯定了你看清了吗...
引用自phommy(石头,竹子,诗) :
虽然不知道是怎么做的,但的确可以做到GC.KeepAlive 方法
引用指定对象,使其从当前例程开始到调用此方法的那一刻为止均不符合进行垃圾回收的条件。
myForm.Show(); ------------------------------------
首先退出方法体后,确实被释放了,但释放的是指向对象的指针:myForm,而不是变量指向的内存.因为Form是引用类型的.因用类型的对象的释放并不是指指向它的指针的释放!
======
myForm 只是相当于个别名,何来释放?
引用自shinaterry(簡簡⿺單單..) (
用.Net就是为了快速开发...知道它是一个非托管资源就可以啦....^o^
我向来以做出不让人理解的事而烦恼,也以自己的见识短小而自卑,请老师以后多多说教,多多说教.
我只是就事论事,可能说话有些冲,先到个歉
这个问题我的理解也只是基于猜测而已。
毕竟.net他对此作了完善的封装。里面具体执行了什么,水平不够只能猜了
所有的窗体运行都在它的UI主线程的管理下运行的,你的一个窗体执行了SHOW,主线程会控制这个窗体的显示.和其它的操作..
而且这个方法是在主线程中的,是主界面的一个按钮的click事件===============================================================
引用自(brucenan999(布鲁斯南))
这不是主线程啊,你的主线程是被Application.Run(...)启起来的啊.
所有的窗体运行都在它的UI主线程的管理下运行的,你的一个窗体执行了SHOW,主线程会控制这个窗体的显示.和其它的操作..
引用自
brucenan999(布鲁斯南) ( 四级(中级)) 信誉:99 2007-06-01 16:07:22 得分:0
?
窗体SHOW之后,虽然你的CLICK函数结束了,但是窗体对象还存在啊,而且被管理着,它自己的生命周期并有结束,直到你把它叉掉...
alert('123');
</script>