System.OutOfMemoryException 在 32 位应用程序中

System.OutOfMemoryException in 32-Bit Application

作为我的硕士论文,我目前正在为 X 射线物理学中的不同任务创建一个软件。该软件是用 Visual C++ 编写的。 Net 使用 Visual Studio 2015,仅适用于 32 位系统。

今天我注意到一个名为 System.OutOfMemoryException in System.Drawing.dll 的错误。
当我将 "large" 文件导入我的应用程序时发生错误。

Visual Studio2015的调试工具告诉我错误发生在下面的函数内部。根据调试工具,我已经在错误应该来自的代码行创建了注释。取消注释下面的其余代码将解决 OutOfMemoryException,但不应该是我的目标。这会使软件的用户友好性降低。

问题:谁能在下面的函数中找到错误(和 post 解决方案),或者有好的提示来解决我的问题?

如果您需要更多信息,请告诉我。如果没有必要,我不想详细介绍(>10.000 行代码,大量物理知识)。

原码:

void ManageComposition::CheckFontSetting(TreeNode^ treenode, bool checklines)
{
    int result;
    if (treenode->Nodes->Count!=0)
    {
        if ((treenode->Tag->GetType()->Name=="Element" && checklines) || treenode->Tag->GetType()->Name=="Composition")
            {
            IEnumerator^ treenodeenum = treenode->Nodes->GetEnumerator();
            while (treenodeenum->MoveNext())
            {
                this->CheckFontSetting(safe_cast<TreeNode^>(treenodeenum->Current),checklines);
            }
        }
    }
    if (treenode->Tag->GetType()->Name=="Composition" && this->WithLines())
    {
        result=safe_cast<Composition^>(treenode->Tag)->CheckCalculationParamters(this->normalizeto100);
        switch (result)
        {
        case 0: 
            treenode->BackColor=Color::LightGreen;
            break;
        case 1: 
            if (this->mode=="calculate intensities")
                treenode->BackColor=Color::Red;
            else if (this->mode=="calculate concentrations")
                treenode->BackColor=Color::LightGreen;
            else if (this->mode=="compare relative intensities")
                treenode->BackColor=Color::Red;
            break;
        case 2: 
            if (this->mode=="calculate concentrations")
                treenode->BackColor=Color::Red;
            else if (this->mode=="calculate intensities")
                treenode->BackColor=Color::LightGreen;
            else if (this->mode=="compare relative intensities")
                treenode->BackColor=Color::Red;
            break;
        case 3:
            treenode->BackColor=Color::Red;
            break;
        }
    }
    // This is the point where the errors occur while handling large lists
// uncommenting the rest of this code will solve the error, but functionality will be lost

    else if (treenode->Tag->GetType()->Name=="Element")
    {
        if (safe_cast<Element^>(treenode->Tag)->GetSymbol()!=treenode->Text)
        {
            if (safe_cast<Element^>(treenode->Tag)->GetIntensity(treenode->Text)!=0.0)
            {
                treenode->NodeFont=gcnew System::Drawing::Font(treenode->TreeView->Font,FontStyle::Bold);
                treenode->Text=treenode->Text;
            }
            else if (safe_cast<Element^>(treenode->Tag)->GetGroupIntensity(treenode->Text)!=0.0)
            {
                treenode->NodeFont=gcnew System::Drawing::Font(treenode->TreeView->Font,FontStyle::Bold);
                treenode->Text=treenode->Text;
            }
            else
            {
                treenode->NodeFont=gcnew System::Drawing::Font(treenode->TreeView->Font,FontStyle::Regular);
                treenode->Text=treenode->Text;
            } // Visual Studio debugging tool points on the condition below
            if (safe_cast<Element^>(treenode->Tag)->IsGroupSelected(treenode->Text) || safe_cast<Element^>(treenode->Tag)->GetTransition(treenode->Text)->IsSelected())
            {
                treenode->BackColor=Color::Aquamarine;
            }
            else
            {
                treenode->BackColor=this->treeview->BackColor;
            } 

        }
        else
        {
            bool red=false;
            if (this->mode=="calculate concentrations" || this->mode=="compare relative intensities")
            {
                if (safe_cast<Composition^>(safe_cast<Element^>(treenode->Tag)->owner)->IsRootComposition())
                {
                    if (safe_cast<Element^>(treenode->Tag)->GetIntensitySum()==0.0)
                    {
                        if (safe_cast<Element^>(treenode->Tag)->GetConcentration()==0.0)
                        {
                            red=true;
                        }
                    }
                }
                else
                {
                    if (safe_cast<Element^>(treenode->Tag)->GetIntensitySum()==0.0)
                    {
                        if (safe_cast<Element^>(treenode->Tag)->GetConcentration()==0.0)
                        {
                            red=true;
                        }
                    }
                }
                array<String^>^ dummy=safe_cast<Element^>(treenode->Tag)->GetRelevantLines();
                if (dummy->Length>1)
                {
                    int x;
                    String^ groupname=safe_cast<Element^>(treenode->Tag)->GetTransition(dummy[0])->GetGroup();
                    for(x=1;x<dummy->Length;x++)
                    {
                        if (groupname!=safe_cast<Element^>(treenode->Tag)->GetTransition(dummy[x])->GetGroup())
                            red=true; 
                    }
                }
            }
            if ((this->mode=="calculate intensities" || this->mode=="compare relative intensities")&& safe_cast<Element^>(treenode->Tag)->GetConcentration()==0.0)
                red=true;
            if (red)
                treenode->BackColor=Color::Red;
            else
                treenode->BackColor=Color::LightGreen;
        } 
    } 
}

根据@Hans Olsson 的想法更新了函数:

void ManageComposition::CheckFontSetting(TreeNode^ treenode, bool checklines)
{

Font^ BoldFont = gcnew System::Drawing::Font(treenode->TreeView->Font, FontStyle::Bold);
Font^ RegularFont = gcnew System::Drawing::Font(treenode->TreeView->Font, FontStyle::Regular);

    int result;
    if (treenode->Nodes->Count!=0)
    {
        if ((treenode->Tag->GetType()->Name=="Element" && checklines) || treenode->Tag->GetType()->Name=="Composition")
            {
            IEnumerator^ treenodeenum = treenode->Nodes->GetEnumerator();
            while (treenodeenum->MoveNext())
            {
                this->CheckFontSetting(safe_cast<TreeNode^>(treenodeenum->Current),checklines);
            }
        }
    }
    if (treenode->Tag->GetType()->Name=="Composition" && this->WithLines())
    {
        result=safe_cast<Composition^>(treenode->Tag)->CheckCalculationParamters(this->normalizeto100);
        switch (result)
        {
        case 0: 
            treenode->BackColor=Color::LightGreen;
            break;
        case 1: 
            if (this->mode=="calculate intensities")
                treenode->BackColor=Color::Red;
            else if (this->mode=="calculate concentrations")
                treenode->BackColor=Color::LightGreen;
            else if (this->mode=="compare relative intensities")
                treenode->BackColor=Color::Red;
            break;
        case 2: 
            if (this->mode=="calculate concentrations")
                treenode->BackColor=Color::Red;
            else if (this->mode=="calculate intensities")
                treenode->BackColor=Color::LightGreen;
            else if (this->mode=="compare relative intensities")
                treenode->BackColor=Color::Red;
            break;
        case 3:
            treenode->BackColor=Color::Red;
            break;
        }
    }
    // This is the point where the errors occur while handling large lists
    // uncommenting the rest of this code will solve the error, but functionality will be lost
    else if (treenode->Tag->GetType()->Name=="Element")
    {
        if (safe_cast<Element^>(treenode->Tag)->GetSymbol()!=treenode->Text)
        {
            if (safe_cast<Element^>(treenode->Tag)->GetIntensity(treenode->Text)!=0.0)
            {
                if (BoldFont) treenode->NodeFont = BoldFont;
                treenode->Text=treenode->Text;
            }
            else if (safe_cast<Element^>(treenode->Tag)->GetGroupIntensity(treenode->Text)!=0.0)
            {
                if (BoldFont) treenode->NodeFont = BoldFont;
                treenode->Text=treenode->Text;
            }
            else
            {
                if (!RegularFont) treenode->NodeFont = RegularFont;
                treenode->Text=treenode->Text;
            }

            // Visual Studio debugging tool points to the condition below

            if (safe_cast<Element^>(treenode->Tag)->IsGroupSelected(treenode->Text) || safe_cast<Element^>(treenode->Tag)->GetTransition(treenode->Text)->IsSelected())
            {
                treenode->BackColor = Color::Aquamarine;
            }
            else
            {
                treenode->BackColor=this->treeview->BackColor;
            } 

        }
        else
        {
            bool red=false;
            if (this->mode=="calculate concentrations" || this->mode=="compare relative intensities")
            {
                if (safe_cast<Composition^>(safe_cast<Element^>(treenode->Tag)->owner)->IsRootComposition())
                {
                    if (safe_cast<Element^>(treenode->Tag)->GetIntensitySum()==0.0)
                    {
                        if (safe_cast<Element^>(treenode->Tag)->GetConcentration()==0.0)
                        {
                            red=true;
                        }
                    }
                }
                else
                {
                    if (safe_cast<Element^>(treenode->Tag)->GetIntensitySum()==0.0)
                    {
                        if (safe_cast<Element^>(treenode->Tag)->GetConcentration()==0.0)
                        {
                            red=true;
                        }
                    }
                }
                array<String^>^ dummy=safe_cast<Element^>(treenode->Tag)->GetRelevantLines();
                if (dummy->Length>1)
                {
                    int x;
                    String^ groupname=safe_cast<Element^>(treenode->Tag)->GetTransition(dummy[0])->GetGroup();
                    for(x=1;x<dummy->Length;x++)
                    {
                        if (groupname!=safe_cast<Element^>(treenode->Tag)->GetTransition(dummy[x])->GetGroup())
                            red=true; 
                    }
                }
            }
            if ((this->mode=="calculate intensities" || this->mode=="compare relative intensities")&& safe_cast<Element^>(treenode->Tag)->GetConcentration()==0.0)
                red=true;
            if (red)
                treenode->BackColor=Color::Red;
            else
                treenode->BackColor=Color::LightGreen;
        } 
    } 
}

注意:应用程序在加载包含数据的文件时使用不到 50 MB 的 Ram。

我同意@Dmitry-T 的观点,您可能需要更改许多字体;只需创建一次粗体等,然后重复使用: 而不是这样的代码:

 treenode->NodeFont=gcnew System::Drawing::Font(treenode->TreeView->Font,FontStyle::Bold);

在函数开始时声明 BoldFont 并执行如下操作:

 if (!BoldFont) BoldFont=gcnew System::Drawing::Font(treenode->TreeView->Font,FontStyle::Bold);
 treenode->NodeFont=BoldFont;