新建的项目,有窗口FORM1,新建一个窗口FORM2
FORM1中有一个按钮,点击后执行如下代码:for (int i = 0; i < 100; i++)
{
    Form2 f = new Form2();
    f.Show();
   f = null;
}打开100个FORM2窗口FORM2窗口中有如下代码:private void Form2_Load(object sender, EventArgs e)
{
    Thread th = new Thread(run);
    th.Start();
}private void run()
{
    Thread.Sleep(10000);
    this.Close();
    this.Dispose();
}窗口Form2在显示10秒后关闭。执行程序后,占用内存10056K,打开100个窗口后占用12928K,关闭100个窗口后占用内存12172K。
尝试使用GC.Collect();强制释放内存,未生效。
当多次点击按钮后,内存占用会越来越高,请问这种情况应该怎么解决?

解决方案 »

  1.   

    using()
    {
       
    }
    在就是用Gc了
    我怎么感觉你那线程怪怪的。
      

  2.   

    GC.Collect();并不会立即释放内存。C#里面的内存释放是不可控的
      

  3.   

    private delegate void DelegateCloseForm();
            private void CloseForm()
            {
                if (this.InvokeRequired)
                {
                    this.BeginInvoke(new DelegateCloseForm(CloseForm));
                }
                else
                {
                    this.Close();
                    this.Dispose();
                }
            }
            private void run()
            {
                Thread.Sleep(10000);
                CloseForm();
            }
      
    *****************************************************************************
    欢迎使用CSDN论坛专用阅读器 : CSDN Reader(附全部源代码) http://feiyun0112.cnblogs.com/
      

  4.   

    使用ThreadPool来限制在实例化线程所带来的累积开销。
      

  5.   

    private void Form2_Load(object sender, EventArgs e)
    {
        WaitCallback wcb = delegate { run(); };
        ThreadPool.QueueUserWorkItem(wcb);
    }
      

  6.   

    如果内存仍然没有回收,可以强制回收:
    GC.Collect();
      

  7.   


    调用这个方法是会释放内存的。还有就是垃圾回收1代 满的时候CLR关闭的时候占用内存10056K,打开100个窗口后占用12928K,关闭100个窗口后占用内存12172K。 
    这个并不能说明你关闭后,就应该还是10056K内存。因为还有其他资源消耗的内存,比如线程,线程在你关闭够不是把上销毁的。
    而且你这里获得的内存也一定准确
      

  8.   


    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Threading;namespace WindowsApplication53
    {
        public partial class Form2 : Form
        {
            public Form2()
            {
                InitializeComponent();
            }        private void Form2_Load(object sender, EventArgs e)
            {
                Thread th = new Thread(run);
                th.Start();
            }        delegate void d();        private void run()
            {
                Thread.Sleep(1000);
                this.Invoke(new d(this.Close));
                GC.Collect();   // 放这里
            }
        }
    }
      

  9.   

    private void run()
    {
         Thread.Sleep(1000);
         this.Invoke(new MethodInvoker(delegate(){this.Close}));
    }
      

  10.   

    lovvver的方法试过,还是不行,内存没有释放,GC.Collect();也没有用。wartim的方法也不行,导致程序异常退出。不过倒是发现,点击最小化将窗口最小化的时候,内存点用就会变到最小,恢复窗口后内存恢复,不过已经释放了一部分。这仅是说明释放的方法,并不实用。继续等待解决办法。或者大家可以建这么一个项目,自己试试看有没有解决办法。
      

  11.   

    有人说调用GC.Collect();可以释放,不过等待到满的时候就会释放,我测试过不行,我使用一个循环进程,将系统内存用完,都没有释放内存,直接C#崩溃~~
      

  12.   


    异常退出?我倒,我试验过了,没有任何的错误,而且按钮按了好几次,内存几乎没有增长
    异常退出是你其它地方有问题吧把form1也贴上,贴全Form1 :using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;namespace WindowsApplication53
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }        private void button1_Click(object sender, EventArgs e)
            {
                for (int i = 0; i < 100; i++)
                {
                    Form2 f = new Form2();
                    f.Show();
                }
            }
        }
    }Form2 :
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Threading;namespace WindowsApplication53
    {
        public partial class Form2 : Form
        {
            public Form2()
            {
                InitializeComponent();
            }        private void Form2_Load(object sender, EventArgs e)
            {
                Thread th = new Thread(run);
                th.Start();
            }        delegate void d();        private void run()
            {
                Thread.Sleep(1000);
                this.Invoke(new d(this.Close));
                GC.Collect();   // 放这里
            }
        }
    }
      

  13.   

    回wartim,异常退出确实是我的问题,但是内存确实没有释放完全。
    启用后占用10052K,开100个窗口后是14240K,关闭后是占用12908K。
      

  14.   

    可能线程资源在GC.Collect();时还没释放所以无法被强制回收吧
    因为何时去调用GC.Collect();放在哪里很难确定,
    要找到一个地方能确定form已经释放而且线程也已经结束的地方调用GC.Collect();但你这个例子里很难找到这种地方
      

  15.   

    回22楼,我上面所指的内存,是当前运行的进程的内存,和其他进程无关。
    因为我另外要做一个软件,在后台打开一个窗口,窗口中有WEB控件,这个WEB控件登录后进行一系列操作,然后关闭窗口,每一分钟大约打开两个窗口,都是在隐藏执行的。
    现在最麻烦的就是内存问题,大约两个小时左右,就可以把1G的内存吃掉,在进程中多处执行GC.Collect();都不管用。
    所以我简化问题,直接开两个最简单的窗口来实验,但看来大家都很少关注过这个问题。
      

  16.   

    Form2:private delegate void CloseHandler();        private void Form2_Load(object sender, EventArgs e)
            {
                WaitCallback wcb = delegate { run(); };
                ThreadPool.QueueUserWorkItem(wcb); 
            }        private void run()
            {
                try
                {
                    Thread.Sleep(10000);
                    CloseHandler handler = closeModule;
                    Invoke(handler);
                }
                catch(Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }        private void closeModule()
            {
                Close();
                Dispose();
                GC.Collect();
            }
    这个代码可以回收,但是就如上面所言,不可能完全回收。
      

  17.   

    for (int i = 0; i < 100; i++)
    {
        Form2 f = new Form2();
        f.Show();
       f = null;
    }——————————————————————————————
    Form2 f;
    for (int i = 0; i < 100; i++)
    {
       f = new Form2();
       f.Show();
    }
      

  18.   

    试试这样写private void Form2_Load(object sender, EventArgs e)
    {
        Thread th = new Thread(run);
        th.Start();
        th.join();
        this.Close();
    }private void run()
    {
        Thread.Sleep(10000);
    }
      

  19.   

    可以用using 关键字,CLR会自动及时销毁
      

  20.   

    试试把线程先退出掉,否则还在占用资源,GC.Collect(); 也不会收集那些资源的
      

  21.   

    c#无须你自己维护代码。GC在适当时候会代劳的,这也是c#为什么比c++安全稳定的原因!
      

  22.   

    这样试试
    GC.Collect();
    GC.WaitForPendingFinalizers();一般.net程序在最小化后会把内存释放,不知道是什么原因
      

  23.   

    用WINDBG看了下,产生100个线程后,在执行第一垃圾回收时
    100个线程的状态是已死亡,但内存没有释放,而是从终结列表移到了终结可达列表。
    所以只有在第2次垃圾回收时才能被回收。垃圾回收是在调用GC.Collect或者0代对象满本执行,完成会会清理终结可达列表。但是之前的线程可能从0代提升到1代,1代没有满时,GC是不会回收的。在点N此按钮后,你多次调用GC.Collect,在用WINDBG查看Threads会发现已经没有死亡还不释放内存的线程了。LZ的情况是存在,启动10M,100个窗体13M,全关闭并垃圾回收后12M,确实不知道为什么。
    但是还有另外个情况你可以看下,你吧窗体最小化,在打开,你发现内存只有3M了。
    然后我又进行了大搞20次操作,基本内存都保持在10M左右。可见应该不会有内存泄漏的问题,垃圾回收(自动)肯定是起作用了。你可以用CLRProfiler看看内存,这个我看不懂 - -!