C#2008 windform程序:
   程序界面有tablelayoutpanel控件,动态布局控件对象(自定义控件图片和文本),发现刷新屏幕是内存上升,直到内存溢出,程序崩溃。
   仔细检查程序,该null、dispose的都做了,仍然不见效果。GC.collect效果不行!
   网上说窗体最小化,内存可以降下,试验证明内存也也确实降低。
   想问问,有没有关于C#内存释放的方法??

解决方案 »

  1.   

    托管代码都是由clr来控制释放内存的,如果有非托管资源需要手动释放了,建议使用using()
      

  2.   

    c# 释放内存就是调用 GC.Collect() 如果它都搞不定,就说明有问题。
    建议使用 DebugDiag 来分析一下到底具体泄漏点,找到泄漏点后对症下药才行。如果方便的话,可以把代码发给我给你看看。
      

  3.   

    以前vb6时代有个api能释放内存,名字忘了
      

  4.   

    靠GC.Collect() 是行不通的...
      

  5.   


    刚找了一下,好像是SetProcessWorkingSetSize这个api,你可以试试[System.Runtime.InteropServices.DllImportAttribute("kernel32.dll", EntryPoint = "SetProcessWorkingSetSize", ExactSpelling = true, CharSet =
    System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true)]
    private static extern int SetProcessWorkingSetSize(IntPtr process, int minimumWorkingSetSize, int maximumWorkingSetSize);public void Dispose()
    {
        GC.Collect();
        GC.SuppressFinalize(this);    if (Environment.OSVersion.Platform == PlatformID.Win32NT)
        {
            SetProcessWorkingSetSize(System.Diagnostics.Process.GetCurrentProcess().Handle, -1, -1);
        }
    }
      

  6.   

    1、GC的运行时间不确定
    2、在程序运行时,可以调用GC,但是应该尽量让各个线程有一段sleep的时间,这样GC线程才会运行。因为GC线程的优先度是很低的。
    3、另外,C#有类似于Java的弱引用,可以随时释放内存。
      

  7.   

    最好上代码,之后Profiling Program,才能找到内存泄露的地方
      

  8.   

    XX.Dispose();一下就可以了。
      

  9.   


    #region "多路设备"
    /// <summary>
    /// 初始化多路设备
    /// </summary>
    private void InitDEV()
    {
            //数据集
    HXData.HXDataSet dsHX = new HXData.HXDataSet();
            //取数据类
    HXDBA wDBA = new HXDBA(); try
    {
    string SqlStr = "SELECT * FROM Equip WHERE DevType =2  ORDER BY DevID";
    string tablename = dsHX.Equip.TableName; if (wDBA.GetData(SqlStr, out dsHX, tablename))
    {
    int n = dsHX.Equip.Rows.Count;
    //清除容器windows TableLayOutPanel中控件
    foreach (UCHMI ctr in LayoutPart.Controls)
    {
    ctr.Dispose();
    }
                    //发现有时候,容器中控件清除不完、故再次清理
    if (this.LayoutPart.Controls.Count >0 ) this.LayoutPart.Controls.Clear(); if (n > 0)
    {
       this.LayoutPart.SuspendLayout();  

     DataRow myRow;
    for (n = 0; n <dsHX.Equip.Rows.Count; n++)
    {
                         //UCHMI 自定义用户控件
    UCHMI HMI = new UCHMI();
    myRow = dsHX.Equip.Rows[n]; HMI.Anchor = AnchorStyles.None;
    HMI.HxDevID = int.Parse(myRow["DevID"].ToString());
    HMI.HxDevNum = int.Parse(myRow["DevNum"].ToString());
    HMI.HxDevType = int.Parse(myRow["DevType"].ToString());
    HMI.HxMark = myRow["Re"].ToString().Trim();
    HMI.HxTelNum = myRow["TelNum"].ToString().Trim();
    HMI.HxDevAdd = myRow["DevAdd"].ToString().Trim();
    HMI.HxDescription = myRow["Re"].ToString().Trim();
    HMI.HxLabel = myRow["Re"].ToString().Trim();
    HMI.Name = HMI.HxDevID.ToString().Trim();
    HMI.HxOnOff = int.Parse(myRow["OnOff"].ToString());
    HMI.HxAlarm = int.Parse(myRow["IsAlarm"].ToString());
    HMI.HxAlarmSms = myRow["AlarmSms"].ToString().Trim();
    HMI.HxAlarmTel  = myRow["AlarmTel"].ToString().Trim(); //关机、0;开机、1 -是否处于告警状态
    if (HMI.HxOnOff == 0)
    {
                            //Properties.Resources.DEV_D; png格式图片
    HMI.HxPicture = Properties.Resources.DEV_D;
    }
    else
    {
    if (HMI.HxAlarm == 1)
    {
                              //Properties.Resources.DEV_D; gif格式图片
    HMI.HxPicture = Properties.Resources.DEV_F;
    HMI.HxColor = HXConst.AlarmColor;
    }
    }

    //绑定右键菜单
    HMI.ContextMenuStrip = this.MenuHX;
    //事件
    HMI.HxClick += new System.EventHandler(this.HMI_HxClick);
    HMI.HxDoubleClick += new System.EventHandler(this.HMI_HxDoubleClick);
    HMI.HxMouseDown += new System.EventHandler(this.HMI_HxMouseDown);
    HMI.HxCardClick += new System.EventHandler(this.HMI_HxCardClick); this.LayoutPart.Controls.Add(HMI);
    HMI = null;
    myRow = null;
    }
    this.LayoutPart.ResumeLayout(true);

    }
    }
    }
    catch (Exception ex)
    {
    HXEx.WriteExLog(ex);
    }
    finally
    {
    dsHX.Dispose();
    wDBA=null;
    GC.Collect();
    GC.WaitForFullGCComplete();
    }
    }