简体   繁体   中英

C# exception OutOfMemory

I would need some help how to handle this exception:

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()

This is what I am doing:

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);
}

Also: Count() for each of the dictionaries is around 300k. I am not running out of physical memory, nor RAM.. I am counting many diferent things with those dictionaries so I need all of them.

Try setting the architecture of your application to 64bit. Then your application should be able to allocate more memory!

A few things to consider.

  • The architecture (32 bit / 64 bit) that you are targeting. Like this answer said already, try compiling for a 64 bit platform if that is an option. 32-bit .NET processes are limited to 2 GB no matter how much RAM your machine's got.

    You can do this by creating a 64 bit configuration in BuildConfiguration ManagerActive solution platformNew… .

    This of course requires that you are not going to develop or run your program on a 32 bit machine.

Even if the above is an option, I think you would do well to consider whether you can change your application design (or more precisely, the way how you persist that data):

  • Do you need to store all that data, or would a subset do? Is there any way you can reduce the data that has to be saved? For example, can some data be derived from other data by applying some fixed rule, so that you would only have to store the latter kind of data?

  • Can you persist your data to some file(s) other than Web/App.config? (Besides: the settings storage mechanism you are currently using should not be abused for storing any kind of data.) If you persisted your dictionaries using some other storage mechanism (such as one file per dictionary), you might be able to...

  • Serialize and persist one dictionary after the other, one at a time. That might enable you to dispose no-longer-needed dictionaries (and their serialized representations) early, you'd only ever have to keep one serialization output in memory at a time. This would likely relieve memory pressure.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM