如何在C#VS 2010 Professional中减少windows窗体应用程序的内存使用

如何在C#VS 2010 Professional中减少windows窗体应用程序的内存使用,c#,winforms,visual-studio-2010,memory-management,C#,Winforms,Visual Studio 2010,Memory Management,我有一个应用程序,它有一个简单的gui,很少有图形,但有很多对象,例如标签文本框和一些面板。 在某些面板上,它运行LDAP查询,在其他面板上,它查询正在运行的进程并检查NIC状态。 当我转到LDAP searcher面板时,内存使用量下降到应用程序30mb,当我返回只运行计时器的主面板时,它跳到大约300mb+然后不断累积,我尽可能经常运行GC.Collect(),在运行主方法后最小化,这样仍然没有效果,我使用了内置项目属性下的优化代码,并剥离了所有正在使用的系统。我是一个相当新的程序员,从我开

我有一个应用程序,它有一个简单的gui,很少有图形,但有很多对象,例如标签文本框和一些面板。
在某些面板上,它运行LDAP查询,在其他面板上,它查询正在运行的进程并检查NIC状态。
当我转到LDAP searcher面板时,内存使用量下降到应用程序30mb,当我返回只运行计时器的主面板时,它跳到大约300mb+然后不断累积,我尽可能经常运行GC.Collect(),在运行主方法后最小化,这样仍然没有效果,我使用了内置项目属性下的优化代码,并剥离了所有正在使用的系统。我是一个相当新的程序员,从我开始做windows窗体到现在才6个月。任何帮助都很好。我的应用程序本质上是一个GUI,它在后台运行一个计时器,然后执行前面提到的查询和一些任务技能。没有太多的内存密集型。gui对象本身会占用我的内存吗

    public MainMethod()
    {
        try
        {

            InitializeComponent();

            notifyIcon1.Visible = true;


            // this.Opacity = .5;
            aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
            aTimer.Interval = 1000 * 10;

            pword();
            this.ShowInTaskbar = false;
            this.Hide();
            this.Visible = false;
           // GC.Collect();
        }
        catch (Exception ex)
        {
            eventWriter(ex);
        }

    }
    public void pword()
    {
        try
        {

            bool nCheck;
            string[] infoArray = new string[4];
            nCheck = checker.checkNetwork();
            int dayNum = 0;

            if (nCheck == true)
            {

                infoArray = checker.checkAD();   //this is similar code to CheckNetwork except it returns values from the user's AD account properties.
                label3.Text = infoArray[0];
                label2.Text = infoArray[2];
                label1.Text = infoArray[3];
                label21.Text = infoArray[0];
                label22.Text = infoArray[1];
                label23.Text = infoArray[2];
                label24.Text = infoArray[3];
                days = infoArray[3];
                dayNum = int.Parse(days);
                if (dayNum <= 15)
                {
                    timedIntervalChanger(2);
                    aTimer.Start();
                    GC.Collect();
                }
            }
            else
            {
                timedIntervalChanger(1);
                aTimer.Start();
                GC.Collect();
            }
        }
        catch (Exception ex)
        {
            eventWriter(ex);
        }

当我展示表单时,内存使用量急剧增加。每个方法都是独立的,我省略了一些对象实例化代码。

我们需要更多信息。但有几点建议:

  • 使用
    using
    关键字,或在处理完所有一次性对象后调用
    Dispose()
  • 确保在侦听完事件后取消注册事件处理程序

  • 我不确定您使用的LDAP库是什么,但在System.DirectoryServices中,许多类(如
    DirectoryEntry
    )实现了
    IDisposable
    ,如果不处理它们,可能会“泄漏”

    我们确实需要更多信息。但有几点建议:

  • 使用
    using
    关键字,或在处理完所有一次性对象后调用
    Dispose()
  • 确保在侦听完事件后取消注册事件处理程序


  • 我不确定您使用的是什么LDAP库,但在System.DirectoryServices中有许多类(如
    DirectoryEntry
    )实现
    IDisposable
    ,如果未处理它们,则可能“泄漏”

    使用性能向导的.NET内存分配选项(位于“分析”菜单中)创建性能会话,该会话将帮助您确定需要在代码中进行哪些更改以减少内存使用。

    使用.NET内存分配选项“分析”菜单中的“性能向导”的一部分,用于创建性能会话,该会话将帮助您确定需要在代码中进行哪些更改以减少内存使用。

    您发现了哪些问题?正如@mjmarsh所说,如果您能向我们展示一些源代码,我们可以为您提供更多帮助。(但是,他的建议是好的。)总体来说,使用了太多的内存,这并不会真正影响机器,但我希望一个小应用程序不要使用300mb的内存。你知道通常的建议是避免GC.Collect,因为它会降低性能,对吗?它迫使对象进入更高的代,并导致每个集合花费更长的时间。如果你真的知道自己在做什么,就使用它,但不要只是在代码中穿插它。计时器的作用是什么?循环(或计时器)中发生的事情是你们应该看的,就像这里的每个人说的,请发布一些代码?你是如何测量内存消耗的?。您能给出所有堆计数器和专用字节计数器中的字节数吗?(所以我们知道要寻找什么样的内存)。你观察到了什么问题?正如@mjmarsh所说,如果你能给我们展示一些源代码,我们可以为你提供更多帮助。(但是,他的建议是好的。)总体来说,使用了太多的内存,这并不会真正影响机器,但我希望一个小应用程序不要使用300mb的内存。你知道通常的建议是避免GC.Collect,因为它会降低性能,对吗?它迫使对象进入更高的代,并导致每个集合花费更长的时间。如果你真的知道自己在做什么,就使用它,但不要只是在代码中穿插它。计时器的作用是什么?循环(或计时器)中发生的事情是你们应该看的,就像这里的每个人说的,请发布一些代码?你是如何测量内存消耗的?。您能给出所有堆计数器和专用字节计数器中的字节数吗?(所以我们知道要查找哪种内存)。我使用System.DirectoryServices和目录条目directorysearcher,本质上是查询LDAP以获取特定用户帐户并返回各种用户对象属性。内存使用在我实例化这些对象之前就开始了。我将对任何未被使用的对象进行检查并调用dispose,我感觉GC.Collect没有收集到它们。你在寻找什么其他信息,我将提供所需的信息。我使用了try-catch finally块,并处理了finally块中的对象,我的内存使用率没有超过19mb。@theJerm-你必须做两件事。保留一个保存委托引用的变量,然后在事件上使用“-=”符号。e、 g:我正在使用System.DirectoryServices和目录条目directorysearcher,本质上是查询LDAP以获取特定的用户帐户并返回各种用户对象属性。内存使用在我实例化这些对象之前就开始了。我将对任何未被使用的对象进行检查并调用dispose,我感觉GC.Collect没有收集到它们。你在寻找什么其他信息,我将提供所需的信息。我使用了try-catch finally块,并处理了finally块中的对象,我的内存使用率没有超过19mb。@theJerm-你必须做两件事。保留一个保存委托引用的变量,然后在事件上使用“-=”符号。例如。:
                String objectName = WindowsIdentity.GetCurrent().Name;
    
    
                if (objectName.Contains("administrator"))
                {
                    connected = false;
                    return connected;
                }
    
                else
                {
    
    
    
    
    
                    // Sets domain
                    string LdapDomain = "mydomain.com"
                    //Sets properties for directory Entry and Searcher
                    string connectionPrefix = "LDAP://" + LdapDomain;
                    DirectoryEntry entry = new DirectoryEntry(connectionPrefix);
                    DirectorySearcher mySearcher = new DirectorySearcher(entry);
    
    
                    mySearcher.Filter = "(&(objectClass=user)(objectCategory=Person)(|(cn=" + objectName + ")(sAMAccountName=" + objectName + ")))";
    
                    //instantiates result object from the search
    
                    SearchResult LDAPresult = mySearcher.FindOne();
    
                    entry = LDAPresult.GetDirectoryEntry();
                    connected = true;
    
                }
                return connected;
            }
            catch
            {
                connected = false;
                return connected;
            }
        }
        public void OnTimedEvent(object source, ElapsedEventArgs e)
        {
            try
            {
    
                notifyIcon1.Visible = true;
                notifyIcon1.ShowBalloonTip(1000 * 9, "Test", "test text", ToolTipIcon.Warning);
    
    
             pword();
            }
            catch (Exception ex)
            {
                eventWriter(ex);
            }
    
    
        }