【问题标题】:C# exception OutOfMemoryC# 异常 OutOfMemory
【发布时间】:2015-07-28 08:18:43
【问题描述】:

我需要一些帮助来处理这个异常:

StackTrace :   at System.Configuration.BaseConfigurationRecord.EvaluateOne(String[] keys, SectionInput input, Boolean isTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult)
   at System.Configuration.BaseConfigurationRecord.Evaluate(FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult, Boolean getLkg, Boolean getRuntimeObject, Object& result, Object& resultRuntimeObject)
   at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
   at System.Configuration.Configuration.GetSection(String sectionName)
   at System.Configuration.ClientSettingsStore.GetConfigSection(Configuration config, String sectionName, Boolean declare)
   at System.Configuration.ClientSettingsStore.WriteSettings(String sectionName, Boolean isRoaming, IDictionary newSettings)
   at System.Configuration.LocalFileSettingsProvider.SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection values)
   at System.Configuration.SettingsBase.SaveCore()
   at System.Configuration.SettingsBase.Save()
   at System.Configuration.ApplicationSettingsBase.Save()
   at BayesianSpamFilter.MainWindow.SaveSettings()

这就是我正在做的:

string percentG = Properties.Settings.Default.PercentG;
string percentB = Properties.Settings.Default.PercentB;
string percentR = Properties.Settings.Default.PercentR;
string percentF = Properties.Settings.Default.PercentF;

string spamDbM = Properties.Settings.Default.SpamDbM;
string spamDbS = Properties.Settings.Default.SpamDbS;
string hamDbM = Properties.Settings.Default.HamDbM;
string hamDbS = Properties.Settings.Default.HamDbS;

private void SaveSettings()
{

    percentG = JsonConvert.SerializeObject(spamPercentageGraham);
    Properties.Settings.Default.PercentG = percentG;

    percentB = JsonConvert.SerializeObject(spamPercentageBurton);
    Properties.Settings.Default.PercentB = percentB;

    percentR = JsonConvert.SerializeObject(spamPercentageRobinson);
    Properties.Settings.Default.PercentR = percentR;

    percentF = JsonConvert.SerializeObject(spamPercentageFisher);
    Properties.Settings.Default.PercentF = percentF;

    spamDbM = JsonConvert.SerializeObject(spamDatabaseMulti);
    Properties.Settings.Default.SpamDbM = spamDbM;

    spamDbS = JsonConvert.SerializeObject(spamDatabaseSingles);
    Properties.Settings.Default.SpamDbS = spamDbS;

    hamDbM = JsonConvert.SerializeObject(hamDatabaseMulti);
    Properties.Settings.Default.HamDbM = hamDbM;

    hamDbS = JsonConvert.SerializeObject(hamDatabaseSingles);
    Properties.Settings.Default.HamDbS = hamDbS;


    Properties.Settings.Default.Save();
}

private void LoadSettings()
{
    spamPercentageGraham = JsonConvert.DeserializeObject<Dictionary<string, double>>(percentG);
    spamPercentageBurton = JsonConvert.DeserializeObject<Dictionary<string, double>>(percentB);
    spamPercentageRobinson = JsonConvert.DeserializeObject<Dictionary<string, double>>(percentR);
    spamPercentageFisher = JsonConvert.DeserializeObject<Dictionary<string, double>>(percentF);

    spamDatabaseMulti = JsonConvert.DeserializeObject<Dictionary<string, int>>(spamDbM);
    spamDatabaseSingles = JsonConvert.DeserializeObject<Dictionary<string, int>>(spamDbS);
    hamDatabaseMulti = JsonConvert.DeserializeObject<Dictionary<string, int>>(hamDbM);
    hamDatabaseSingles = JsonConvert.DeserializeObject<Dictionary<string, int>>(hamDbS);
}

另外:每个字典的Count() 大约是 300k。我没有用完物理内存,也没有用完 RAM。我用这些字典计算了许多不同的东西,所以我需要它们。

【问题讨论】:

  • 在你的问题结束时,我不得不微笑了一下。一切看起来都很合理,直到你提到,几乎不值得一提的是,这些词典是巨大的...... :-D
  • 嗯,为一些“标准”而编译,从来没有像现在这样大。如何将编译方法更改为 64b?
  • 必须有比同时将所有这些大字典加载到内存中更好的解决方案。
  • 您可以尝试一次保存一个。目前,您拥有内存中的所有字典以及它们的所有序列化。一次一个将取消序列化的范围并将其装箱。就我个人而言,我从来没有想过要像这样存储数据。我会使用设置来选择一个文件夹,然后用文件流加载和保存。简单的 name= value 文本就可以了。
  • 设置并不意味着存储数据:有数据库和硬盘驱动器文件。设置旨在存储...设置,就是说一些字符串和布尔标志,它们会改变应用程序的某些部分的行为方式,但肯定不会改变它的数据。

标签: c# exception memory stack out-of-memory


【解决方案1】:

需要考虑的一些事项。

  • 您的目标架构(32 位/64 位)。 就像this answer 已经说过的那样,如果可以选择,请尝试针对 64 位平台进行编译。无论您的机器有多少 RAM,32 位 .NET 进程都被限制为 2 GB。

    您可以通过在 BuildConfiguration ManagerActive solution platformNew...中创建 64 位配置来做到这一点/em>。

    这当然要求您不要在 32 位机器上开发或运行您的程序。

即使以上是一个选项,我认为您最好考虑是否可以更改应用程序设计(或更准确地说,是您保存数据的方式):

  • 您需要存储所有数据,还是只存储一个子集?有什么方法可以减少必须保存的数据?例如,是否可以通过应用某些固定规则从其他数据中导出某些数据,从而只需要存储后一种数据?

  • 您可以将您的数据保存到 Web/App.config 以外的其他文件中吗?(另外:您当前使用的设置存储机制不应该被滥用来存储 任何种数据。)如果您使用其他一些存储机制(例如每个字典一个文件)来持久化您的字典,您可能能够...

  • 一个接一个地序列化和持久化一个字典,一次一个。这可能使您能够及早处理不再需要的字典(及其序列化的表示形式),您应该一次只需要在内存中保留一个序列化输出。这可能会减轻内存压力。

【讨论】:

    【解决方案2】:

    尝试将应用程序的架构设置为 64 位。那么您的应用程序应该能够分配更多内存!

    【讨论】:

    • 如果是在32位机器上运行呢?
    • 因为程序有错误而为机器分配更多内存绝不是可行的解决方案。
    • @Jevans92 那他就不能把所有这些列表都保存在内存中!
    • 他已经把内存中的所有列表都保存了,问题在于保存是他也有它们的所有序列化......
    猜你喜欢
    • 2016-12-16
    • 1970-01-01
    • 2017-03-19
    • 2018-06-18
    • 2015-04-25
    • 2016-04-26
    • 2014-07-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多