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;
作为我的硕士论文,我目前正在为 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;