2016-11-23 37 views
0

作爲我的碩士論文,我目前正在爲X-Ray-Physics中的不同任務創建軟件。該軟件使用Visual Studio 2015以Visual C++ .Net編寫,僅適用於32位系統。32位應用程序中的System.OutOfMemoryException

今天我注意到System.Drawing.dll中出現一個名爲「System.OutOfMemoryException」的錯誤。 當我將「大」文件導入到我的應用程序中時發生錯誤。

Visual Studio 2015的調試工具告訴我,錯誤發生在下面的函數中。根據調試工具,我已經在代碼的錯誤應該來自的地方創建了一條評論。取消註釋下面的代碼的其餘部分將解決OutOfMemoryException,但不應該成爲我的目標。它會使軟件的用戶友好性降低。

問題:任何人都可以在下面的函數中找到一個錯誤(併發布解決方案),或者有一個很好的提示,所以解決我的問題?

如果您需要更多信息,請告訴我。如果沒有必要,我不想過多細節(> 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奧爾森的想法:

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,同時加載包含數據的文件。

+1

與NodeFont多少節點改變在那兒?我懷疑你分配了太多的Font實例,並且每個實例都很重。 –

+0

我想大約45分鐘。給我10分鐘,我會檢查出來。 – scherzkrapferl

+1

這與你的問題沒有關係,但是你需要修改一些東西:1.使用枚舉而不是字符串(例如'this-> mode'),2.使用'for each'循環而不是枚舉器直接使用'dynamic_cast'而不是反射,或者更好的辦法是使用多態性。 –

回答

0

我同意@德米特里 - T,你可能需要很多字體變化;剛剛創建粗體字等一次,然後重用: 而不是代碼,如:

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

在功能開始申報粗體字,做一些事情,如:

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

謝謝你的回答!我會試試看,並會向你報告:-) – scherzkrapferl

+0

對不起,評論bevore。您的解決方案完美運作非常感謝!這條if-conditions是提示。 – scherzkrapferl