Form1: Form2 rf = new Form2(); if (rf.ShowDialog() == DialogResult.OK)
{
rf.Dispose();
rf = null;
GC.Collect();
}
Form2只是一个简单的窗体,这时候查看物理内存状态,如果我不停的打开Form2并将之关闭,所占有的物理内存并不释放。盼高手回复!
开发环境wce 5.0
{
rf.Dispose();
rf = null;
GC.Collect();
}
Form2只是一个简单的窗体,这时候查看物理内存状态,如果我不停的打开Form2并将之关闭,所占有的物理内存并不释放。盼高手回复!
开发环境wce 5.0
GC.Collect();
并不是马上执行~~~~
是可以自动的垃圾回收,但不是实时的
{
rf.Dispose();
rf = null;
GC.Collect();
}
-------------------------------------------------------------GC.Collect(); /////LZ难道认为在这里就释放?rf的作用域还没结束。垃圾回收一个重要的原则是:只要访问的到就不释放。很显然在if{}后rf还可以访问的到,所以无论你怎么操作都不会回收。你把rf = null; 注销掉,那么,在if{}后面rf里面的所有成员都可以访问到,不会释放。
///////////////////////////
垃圾回收一个重要的原则是:只要访问的到就不释放。
///////////////////////////
这里说的访问不到不是变量,是对象,释放的也是对象,不是变量,变量的内存是堆栈上的,Form2是个类型,这个是在程序堆上的。这个时候,已经没有任何的变量可以访问到这个new Form2对象了。这个对象已经是符合被回收条件了。此时调用GC.Collect()肯定会释放的。如下测试程序:
//////////////////////////////////////////////////////using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;namespace WinceTestProject01
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
} MEMORYSTATUS mem1, mem2;
private void button1_Click(object sender, EventArgs e)
{
GlobalMemoryStatus(ref mem1);
Form2 frm = new Form2();
frm.ShowDialog();
frm.Dispose();
frm = null;
GC.Collect();
GlobalMemoryStatus(ref mem2);
MessageBox.Show(
(mem1.dwAvailPhys ).ToString() +
"\r\n" +
(mem2.dwAvailPhys ).ToString()
); } [StructLayout(LayoutKind.Sequential)]
public struct MEMORYSTATUS
{
public int dwLength;
public int dwMemoryLoad;
public int dwTotalPhys;
public int dwAvailPhys;
public int dwTotalPageFile;
public int dwAvailPageFile;
public int dwTotalVirtual;
public int dwAvailVirtual;
} [DllImport("coredll.dll", EntryPoint = "GlobalMemoryStatus")]
public static extern void GlobalMemoryStatus(
ref MEMORYSTATUS lpBuffer
);
}
测试结果如下:17346560
1728512017170432
1717043217170432
1721548817215488
1721548817215488
1721548817215488
17215488单位是byte可见是会立刻回收的。
Form2 rf = new Form2();
rf.textBox1.Text = "123";
if (true)
{
rf.Dispose();
//rf = null;
GC.Collect();
}
string str = rf.textBox1.Text;
MessageBox.Show(str);如果照你的意思,那么string str = rf.textBox1.Text;这一行就会报错,或者str为空。因为照你的理论已经会上了。
自己看吧
这个看不出问题???.net内存是托管的没错。只是限於.net clr,那么,.net clr运行要内存不?如果实际的内存占用量减少了。你能说你的clr托管的内存他没释放?不释放实际内存怎么减少的?测试环境:wince 5.0
打开我的电脑->根目录,启动程序,点击按钮操作。
首先你要明确rf只是个引用,为了方便理解,我们可以理解为rf为指向Form2对象的指针。
rf置为null也仅仅是把这个引用置为空,但对象本身并没有销毁。直到作用域结束后才被销毁。看以下代码
Form2 rf = new Form2();
Form2 rf1 = null;
rf.textBox1.Text = "123";
if (true)
{
rf.Dispose();
rf1 = rf;
rf = null;
GC.Collect();
}
string str = rf1.textBox1.Text;
Form2 rf = new Form2();
Form2 rf1 = null;
rf.textBox1.Text = "123";
if (true)
{
rf.Dispose();
rf1 = rf;
rf = null;
rf1 = null;
GC.Collect();
}
string str = rf1.textBox1.Text;
你是不是还搞个引用指向这个new Form2对象????
仔细看看我的回复吧:
//////////////////////////////////////////
这里说的访问不到不是变量,是对象,释放的也是对象,不是变量,变量的内存是堆栈上的,Form2是个类型,这个是在程序堆上的。这个时候,已经没有任何的变量可以访问到这个new Form2对象了。这个对象已经是符合被回收条件了。此时调用GC.Collect()肯定会释放的。
//////////////////////////////////////////
重复了几次了。变量是在堆栈上分配的,new Form2是在堆上分配的,你保留指向堆上对象的引用。那垃圾回收肯定不会回收。你反复帖出这样的代码。我只能说你没看明白我帖的这段。其实你明白这个道理。但不知道你为什么非要弄这个例子,想说明什么?
1 using System.Data;2 public void MemoryTracking()
3 {
4 try
5 {
6 for (int i = 0; i < 100; i ++)
7 {
8 DataTable dt = new DataTable();
9 fillTable(dt);
10
11 dt.Dispose();
12 dt = null;
13 }
14 }
15 catch(Exception ex)
16 {
17 throw (ex);
18 }
19 }private void fillTable(DataTable dt)
{
// 为 dt 创建10列,5000 条有数据的 DataRow
}
注意哦,如果吧第 8 行代码移动到第 6 行之前,那效果完全不一样哦。
if (rf.ShowDialog() == DialogResult.OK)
{
rf.Dispose();
rf = null;
GC.Collect();
}如果执行了 GC 那一句,内存就会回收,除非其他地方还有对窗体的引用。不知道楼主是怎么看内存的,任务管理器好像不大精确,销毁几个窗体不
会收回大量内存,所以肉眼看不出来。可以一次创建1000个窗体,然后回
收一下看有没有效果。免责声明:死机莫找俺^_^。祝楼主好运。