Current filter:
                                You should refresh the page.
                                  • My application is exceptioning with an out of memory error.
                                    I traced it to the Dictionary.
                                    I couldn't see what I wasn't doing correctly and then when I searched I saw that you've had issues with it in some builds.
                                    I upgraded to 19.1.6 and I still have the issue.
                                    I need to know if I have to comment out my calls to the Dictionary and publish my code to my users, or if this is a known problem that has a solution from you.
                                    I have another ticket but I piggy-backed onto someone else's ticket where the problem was resolved several versions ago so that ticket may be at the bottom of your pile but I'd like to know what I can do ASAP for my users.  I realize it absolutely could be a problem of mine, so if you confirm the dictionary is good in v19.1.6 I will examine my code more closely.
                                    Thank you.

                                • Sasha (DevExpress Support) 10.07.2019

                                  Hello Marlene,

                                  We need some time to check whether the issue occurs in version 19.1.6. In the meantime, I noticed that you specified the XtraGrid product in your ticket. Would you please clarify, whether you are using XtraSpellChecker with our GridControl? Is it possible to provide a small sample project that illustrates how you are using XtraSpellChecker in your application?

                                • Marlene 10.07.2019

                                  Sure, no problem.  Anything I can do to help.

                                  I believe selecting XtraGrid Suite was a mistake.  Sorry about that.

                                  I will attach some code snippets.  I hope that helps and/or that you can create a sample but if you need me to let me know.

                                  I create the spellcheck controls myself.  I found that if I drop them in the designer, they want to spell check everything.

                                  This code is from the form where people are exceptioning after the from code is a class I wrote.

                                  // Global variables SpellChecker spellChecker1; SpellChecker spellChecker2; SpellChecker spellChecker3; SpellChecker spellChecker4; SpellChecker spellChecker5; OptionsSpelling optionsSpelling1; OptionsSpelling optionsSpelling2; OptionsSpelling optionsSpelling3; OptionsSpelling optionsSpelling4; OptionsSpelling optionsSpelling5; // Consstructor public frmJobEntry3(dsJobs.JobsDataTable dtJobsIn, dsP21Order.p21_order_viewDataTable dt, bool bInUse = false, int tabToOpenLower = -1, bool argFirstTime = false, int tabToOpen = -1) { dtJobs = dtJobsIn; jobRow = (dsJobs.JobsRow)dtJobs.Rows[0]; iRowCurrentJob = -1; // Some stuff we'll need later that OpenJob() got for us. dtP21Order = dt; // jobRow = row; //jobControlCurrentlyOpen = row.Control; jobControlCurrentlyOpen = jobRow.Control; bJobIsLockedInUse = bInUse; bFirstTime = argFirstTime; InitializeComponent(); InitializeComponentSpellCheck(); etc. // I wrote my own InitializeComponent for the spell check controls. They check MemoEdits. private void InitializeComponentSpellCheck() { spellChecker1 = new SpellChecker(); spellChecker2 = new SpellChecker(); spellChecker3 = new SpellChecker(); spellChecker4 = new SpellChecker(); spellChecker5 = new SpellChecker(); optionsSpelling1 = new OptionsSpelling(); optionsSpelling2 = new OptionsSpelling(); optionsSpelling3 = new OptionsSpelling(); optionsSpelling4 = new OptionsSpelling(); optionsSpelling5 = new OptionsSpelling(); spellChecker1.CheckAsYouTypeOptions.CheckControlsInParentContainer = true; spellChecker1.Culture = new CultureInfo("en-US"); spellChecker1.ParentContainer = meComplaint; spellChecker1.SetShowSpellCheckMenu(meComplaint, true); spellChecker1.SetSpellCheckerOptions(meComplaint, optionsSpelling1); spellChecker2.CheckAsYouTypeOptions.CheckControlsInParentContainer = true; spellChecker2.Culture = new CultureInfo("en-US"); spellChecker2.ParentContainer = meAccessInfo; spellChecker2.SetShowSpellCheckMenu(meAccessInfo, true); spellChecker2.SetSpellCheckerOptions(meAccessInfo, optionsSpelling2); spellChecker3.CheckAsYouTypeOptions.CheckControlsInParentContainer = true; spellChecker3.Culture = new CultureInfo("en-US"); spellChecker3.ParentContainer = meResolution; spellChecker3.SetShowSpellCheckMenu(meResolution, true); spellChecker3.SetSpellCheckerOptions(meResolution, optionsSpelling3); spellChecker4.CheckAsYouTypeOptions.CheckControlsInParentContainer = true; spellChecker4.Culture = new CultureInfo("en-US"); spellChecker4.ParentContainer = meInternalNotes; spellChecker4.SetShowSpellCheckMenu(meInternalNotes, true); spellChecker4.SetSpellCheckerOptions(meInternalNotes, optionsSpelling4); spellChecker5.CheckAsYouTypeOptions.CheckControlsInParentContainer = true; spellChecker5.Culture = new CultureInfo("en-US"); spellChecker5.ParentContainer = meShipInstructions; spellChecker5.SetShowSpellCheckMenu(meShipInstructions, true); spellChecker5.SetSpellCheckerOptions(meShipInstructions, optionsSpelling5); } // Form Load private void frmJobEntry3_Load(object sender, EventArgs e) { // This is at the bottom // 08/30/19 - Call into new class I wrote today to set up the spellchecker with dictionaries and the controls we want it to check OperationSpellCheck spellIt = new OperationSpellCheck(); spellIt.LoadDictionariesAndSetupSpellChecker(spellChecker1); spellIt.LoadDictionariesAndSetupSpellChecker(spellChecker2); spellIt.LoadDictionariesAndSetupSpellChecker(spellChecker3); spellIt.LoadDictionariesAndSetupSpellChecker(spellChecker4); spellIt.LoadDictionariesAndSetupSpellChecker(spellChecker5); } // The class I wrote public class OperationSpellCheck { public void LoadDictionariesAndSetupSpellChecker(SpellChecker spellChecker1) { LoadISpellDictionaries(spellChecker1); spellChecker1.Culture = CultureInfo.InvariantCulture; spellChecker1.SpellCheckMode = SpellCheckMode.AsYouType; } private void LoadISpellDictionaries(SpellChecker spellChecker1) { spellChecker1.Dictionaries.Clear(); // The ISpell Dictionary SpellCheckerISpellDictionary dictionary = new SpellCheckerISpellDictionary(); Stream affStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("CmsDotNet.Dictionaries.english.aff"); Stream dicStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("CmsDotNet.Dictionaries.american.xlg"); Stream alphStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("CmsDotNet.Dictionaries.EnglishAlphabet.txt"); // Dictionary, Grammar, Alphabet dictionary.LoadFromStream(dicStream, affStream, alphStream); spellChecker1.Dictionaries.Add(dictionary); LoadCustomDictionary(spellChecker1); } private void LoadCustomDictionary(SpellChecker spellChecker1) { SpellCheckerCustomDictionary customDictionary = new SpellCheckerCustomDictionary(); string path = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "CMS 2.0"); customDictionary.AlphabetPath = path + @"\Dictionaries\EnglishAlphabet.txt"; customDictionary.DictionaryPath = path + @"\Dictionaries\CustomEnglish.dic"; customDictionary.Culture = CultureInfo.InvariantCulture; spellChecker1.Dictionaries.Add(customDictionary); } }

                                  Here is the exception stack:

                                  See the end of this message for details on invoking
                                  just-in-time (JIT) debugging instead of this dialog box.

                                  ************** Exception Text **************
                                  System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
                                     at System.Collections.Generic.List`1.set_Capacity(Int32 value)
                                     at System.Collections.Generic.List`1.EnsureCapacity(Int32 min)
                                     at System.Collections.Generic.List`1.Add(T item)
                                     at DevExpress.XtraSpellChecker.SpellCheckerDictionaryBase.AddWordToDoubleMetaphoneIndexes(String word, Int32 index)
                                     at DevExpress.XtraSpellChecker.SpellCheckerDictionaryBase.FillDoubleMetaphoneIndexes()
                                     at DevExpress.XtraSpellChecker.SpellCheckerDictionaryBase.OnDictionaryChanged()
                                     at DevExpress.XtraSpellChecker.SpellCheckerISpellDictionary.LoadFromStream(Stream dictionaryStream, Stream grammarStream, Stream alphabetStream)
                                     at CmsDotNet.OperationSpellCheck.LoadISpellDictionaries(SpellChecker spellChecker1)
                                     at CmsDotNet.OperationSpellCheck.LoadDictionariesAndSetupSpellChecker(SpellChecker spellChecker1)
                                     at CmsDotNet.frmJobEntry3.frmJobEntry3_Load(Object sender, EventArgs e)
                                     at System.Windows.Forms.Form.OnLoad(EventArgs e)
                                     at System.Windows.Forms.Form.OnCreateControl()
                                     at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
                                     at System.Windows.Forms.Control.CreateControl()
                                     at System.Windows.Forms.Control.WmShowWindow(Message& m)
                                     at System.Windows.Forms.Control.WndProc(Message& m)
                                     at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
                                     at System.Windows.Forms.Form.WmShowWindow(Message& m)
                                     at System.Windows.Forms.Form.WndProc(Message& m)
                                     at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
                                     at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
                                     at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

                                • Marlene 10.07.2019

                                  I realized earlier this morning that I wasn't doing some of the cleanup I could've been doing, so to my FormClosed() event I added:

                                  // 10/7/19 - To help memory leak? optionsSpelling1 = null; optionsSpelling2 = null; optionsSpelling3 = null; optionsSpelling4 = null; optionsSpelling5 = null; spellChecker1.Dispose(); spellChecker2.Dispose(); spellChecker3.Dispose(); spellChecker4.Dispose(); spellChecker5.Dispose();

                                  But that didn't help.  So when I no longer could see anything my own code was missing, I googled for a memory leak in your spellchecker and found the hits of previous versions.

                                1 Solution

                                Creation Date Importance Sort by


                                I noticed that you create a separate SpellChecker instance for each spelled editor and load dictionaries for each SpellChecker. Note that loaded dictionaries may allocate a significant amount of memory. There are no Stream.Close/Dispose method calls in the provided code snippet, so it looks like the dictionary streams stayed open after a form with SpellCheckers was closed.

                                As far as I understand your scenario, you wish to prevent check spelling in some controls on the form. If so, to accomplish the task, use the following approach:

                                1. Create one SpellChecker instance and set the SpellChecker.ParentContainer property to the form where the spelled editors are located.
                                2. Exclude the required editors using the SpellChecker.SetCanCheckText(Control, Boolean) method.
                                spellChecker1.SetCanCheckText (editorName, false);

                                Alternatively, you can handle the BeforeCheck event and set the e.Cancel parameter to true to forbid checking in a certain control.

                                If you need to check spelling on several forms, you can create several SpellChecker instances with a shared dictionary collection. Use the SharedDictionaryStorage component to store and share dictionaries between spell checkers in your application. Refer to the How to: Use the SharedDictionaryStorage Component article for clarification.

                                Show all comments
                                • Marlene 10.08.2019

                                  Hi, thank you for the analysis of my code.
                                  I made some code changes.  I still don't see the memory freeing when the form is closed.
                                  A summary of what I did is:

                                  1. Allocate only once instance of SpellChecker and OptionsSpelling to be used with the form as the parent container, versus allocating five of each for use with the five memoedits I want to spellcheck.
                                  2. Explicitly Close and Dispose the 3 stream objects I allocate, when the form is closed.
                                  3. Explcitly set my spellchecker and optionsspelling objects to null when the form is closed.
                                  The memory *usage* is better, obviously because I've cut those 5 objects down to one,  but as I open and close the form I see the memory increasing but not going down.  Is this a waiting game and I  need to be more patient and wait for GC to happen?  If so, how long do you recommend and is there anything I can do to give it a nudge?
                                  // global variables // 10/08/19 OperationSpellCheck spellIt; SpellChecker spellChecker1; //SpellChecker spellChecker2; //SpellChecker spellChecker3; //SpellChecker spellChecker4; //SpellChecker spellChecker5; OptionsSpelling optionsSpelling1; //OptionsSpelling optionsSpelling2; //OptionsSpelling optionsSpelling3; //OptionsSpelling optionsSpelling4; //OptionsSpelling optionsSpelling5; // Constructor public frmJobEntry3(dsJobs.JobsDataTable dtJobsIn, dsP21Order.p21_order_viewDataTable dt, bool bInUse = false, int tabToOpenLower = -1, bool argFirstTime = false, int tabToOpen = -1) { dtJobs = dtJobsIn; jobRow = (dsJobs.JobsRow)dtJobs.Rows[0]; iRowCurrentJob = -1; // Some stuff we'll need later that OpenJob() got for us. dtP21Order = dt; // jobRow = row; //jobControlCurrentlyOpen = row.Control; jobControlCurrentlyOpen = jobRow.Control; bJobIsLockedInUse = bInUse; bFirstTime = argFirstTime; InitializeComponent(); InitializeComponentSpellCheck(); etc. private void InitializeComponentSpellCheck() { spellChecker1 = new SpellChecker(); //spellChecker2 = new SpellChecker(); //spellChecker3 = new SpellChecker(); //spellChecker4 = new SpellChecker(); //spellChecker5 = new SpellChecker(); optionsSpelling1 = new OptionsSpelling(); //optionsSpelling2 = new OptionsSpelling(); //optionsSpelling3 = new OptionsSpelling(); //optionsSpelling4 = new OptionsSpelling(); //optionsSpelling5 = new OptionsSpelling(); spellChecker1.CheckAsYouTypeOptions.CheckControlsInParentContainer = true; spellChecker1.Culture = new CultureInfo("en-US"); //spellChecker1.ParentContainer = meComplaint; spellChecker1.ParentContainer = this; spellChecker1.SetShowSpellCheckMenu(meComplaint, true); spellChecker1.SetSpellCheckerOptions(meComplaint, optionsSpelling1); //spellChecker2.CheckAsYouTypeOptions.CheckControlsInParentContainer = true; //spellChecker2.Culture = new CultureInfo("en-US"); //spellChecker2.ParentContainer = meAccessInfo; //spellChecker2.SetShowSpellCheckMenu(meAccessInfo, true); //spellChecker2.SetSpellCheckerOptions(meAccessInfo, optionsSpelling2); //spellChecker3.CheckAsYouTypeOptions.CheckControlsInParentContainer = true; //spellChecker3.Culture = new CultureInfo("en-US"); //spellChecker3.ParentContainer = meResolution; //spellChecker3.SetShowSpellCheckMenu(meResolution, true); //spellChecker3.SetSpellCheckerOptions(meResolution, optionsSpelling3); //spellChecker4.CheckAsYouTypeOptions.CheckControlsInParentContainer = true; //spellChecker4.Culture = new CultureInfo("en-US"); //spellChecker4.ParentContainer = meInternalNotes; //spellChecker4.SetShowSpellCheckMenu(meInternalNotes, true); //spellChecker4.SetSpellCheckerOptions(meInternalNotes, optionsSpelling4); //spellChecker5.CheckAsYouTypeOptions.CheckControlsInParentContainer = true; //spellChecker5.Culture = new CultureInfo("en-US"); //spellChecker5.ParentContainer = meShipInstructions; //spellChecker5.SetShowSpellCheckMenu(meShipInstructions, true); //spellChecker5.SetSpellCheckerOptions(meShipInstructions, optionsSpelling5); } // Form Load ... // 08/30/19 - Call into new class I wrote today to set up the spellchecker with dictionaries and the controls we want it to check spellIt = new OperationSpellCheck(); spellIt.LoadDictionariesAndSetupSpellChecker(spellChecker1); //spellIt.LoadDictionariesAndSetupSpellChecker(spellChecker2); //spellIt.LoadDictionariesAndSetupSpellChecker(spellChecker3); //spellIt.LoadDictionariesAndSetupSpellChecker(spellChecker4); //spellIt.LoadDictionariesAndSetupSpellChecker(spellChecker5); // Form Closed ... spellIt.UnloadDictionaries(); spellChecker1.Dispose(); spellChecker1 = null; optionsSpelling1 = null;
                                • Yulia (DevExpress Support) 10.08.2019

                                  Please send me the implementation of the OperationSpellCheck class. I will recreate your scenario on my side and check if anything can be optimized here.

                                • Marlene 10.08.2019

                                  Yes, I apologize, I thought I had copied that in my post this morning.  I have comments in my code that may or may not be relevant to the problem so ignore or read as you see fit.  To the class I had added a destructor but I didn't think it was getting called so I moved the code to a routine I could explicitly call to be sure I was deallocating resources...only I am not sure, so thanks for your help!

                                • Yulia (DevExpress Support) 10.09.2019

                                  Thank you for providing your code. I need additional time to prepare a test project based on it. I will contact you as soon as I can.

                                • Yulia (DevExpress Support) 10.10.2019

                                  I created a sample based on your code (see the attachment). I profiled this project with ANTS Memory Profiler v10, but didn't find any memory leaks.
                                  I found that the OptionsSpelling, OperationSpellCheck and SpellChecker objects are placed into the finalizer queue. So, these objects will be collected later depending on the garbage collector strategy. Refer to the What are the Finalizer Queue and Control+ThreadMethodEntry? article for clarification.

                                  If the behavior you faced is different, please modify the attached project to show the problem or send us your test project for research.

                                • Marlene 10.10.2019

                                  OK, thank you for all your work.  I will pick up where you left off and give you a status soon.

                                • Marlene 10.10.2019

                                  So you are saying that your SpellChecker and OptionsSpelling components aren't leaking memory and my OperationSpellCheck class is okay too but they're going to the finalizer queue where it's out of my control when resources get freed?  I realize that if this problem isn't in your components then it is not up to you to solve.  Is that what you are saying?  Because if there's nothing wrong with T821251 and that is the exact code in my application, then I need to figure out what's going on with GC in our systems?  Thanks.

                                • Yulia (DevExpress Support) 10.11.2019

                                  Yes, I meant that there is no memory leak in that project. However, the collection of the unused objects is postponed, since they are put into a finalization queue.
                                  As described in the Fundamentals of garbage collection MSDN article: "When a finalizable object is discovered to be dead, its finalizer is put in a queue so that its cleanup actions are executed, but the object itself is promoted to the next generation. Therefore, you have to wait until the next garbage collection that occurs on that generation (which is not necessarily the next garbage collection) to determine whether the object has been reclaimed."

                                  If you wish to release resources immediately when the form with a SpellChecker is closed, you can call the code below in the Form.Closed event handler:

                                  System.GC.Collect(); ystem.GC.WaitForPendingFinalizers(); // this method may block while it runs the finalizers System.GC.Collect();

                                  Also, I recommend you remove the destructor for your OperationSpellCheck class. In C#, the destructor implicitly calls Finalize in the base class of the object. When a class contains a destructor, an entry is created in the Finalize queue. See the Destructors MSDN article for more information.
                                  In your code, you already released the unmanaged resources in the OperationSpellCheck.UnloadDictionaries method, so there is no need to perform the same operation in the destructor.

                                  I modified my previous project to demonstrate this approach in action. I also profiled the modified project with ANTS Memory Profiler v10, and it does not indicate the OptionsSpelling, OperationSpellCheck and SpellChecker objects in memory after the Form1 form is closed.

                                  I have attached the updated sample for your reference.

                                • Marlene 10.11.2019

                                  To be clear, you do want me to force garbage collection with those three lines of code, even though in the StackOverflow post you cited, the author clearly states: I do not recommend running this code normally.
                                  As a test, I put those instructions in my code and yes the memory usage declined when the form with the dictionary closed, but I thought that should be used just "as a test".
                                  I will say, that when I searched for calls to WaitFOrPendingFinalizers() in my code, I see that I am also forcing GC when I use the Excel interop.  Perhaps it is necessary there, and here, so those instructions are acceptable for isolated cases such as these?
                                  Thank you very much for your attention to this problem of ours!

                                • Yulia (DevExpress Support) 10.14.2019

                                  I guess that in the What are the Finalizer Queue and Control+ThreadMethodEntry? article, Paul Williams meant that in a general case, there is no need to manually force the garbage collection since the garbage collector will do the job sooner or later.
                                  However, this approach is acceptable in some cases, for instance, MSDN recommends calling the GC.Collect method for testing.

                                  I provided the previous sample to demonstrate that there is no memory leak, and the OptionsSpelling, OperationSpellCheck, and SpellChecker objects are properly disposed of after the finalizer threads are run.

                                  As for your real project, in my opinion, there is no need to force the garbage collection in your scenario.

                                • Marlene 10.15.2019

                                  I'm not clear on what you are recommending.
                                  Using the spellcheck component and my class eventually puts the user in an out of memory exception.
                                  Forcing garbage collection when the forms containing spellcheck processing close is freeing the memory.
                                  Calling GC.Collect for testing only showed me that it works.
                                  So what does it mean when you say in your opinion there is no need to force garbage collection?  If I don't, the application exceptions.

                                • Yulia (DevExpress Support) 10.16.2019

                                  It appears I understood you incorrectly. I thought that OutOfMemoryException was solved with the instructions from my answer.

                                  Objects placed into the finalization queue should be collected by the garbage collector when the application lacks memory, and it should not be the OutOfMemoryException in this case.

                                  I could not replicate the issue with my test project (without calling the GC.Collect method directly). I recorded a video to demonstrate how the garbage collector works in this scenario (see the attachment).

                                  It appears that the cause of the OutOfMemoryException in your application is not related to SpellChecker. I recommend you profile your application with a memory profiler tool to find possible memory leaks.

                                  Let me know if I can be of more help.

                                • Marlene 10.17.2019

                                  Yes, the OutOfMemoryException is solved with the instructions from your answer.  So what does it mean when you say in your opinion there is no need to force garbage collection?  If I don't force it, we run out of memory. 

                                • Yulia (DevExpress Support) 10.18.2019

                                  >>So what does it mean when you say in your opinion there is no need to force garbage collection?  If I don't force it, we run out of memory.<<
                                  As you can see in my previous video, I created and opened the Form1 form many times, however, the allocated memory wasn't constantly increasing.
                                  As explained in the Garbage Collection MSDN article: "... However, memory is not infinite. Eventually the garbage collector must perform a collection in order to free some memory. The garbage collector's optimizing engine determines the best time to perform a collection, based upon the allocations being made. When the garbage collector performs a collection, it checks for objects in the managed heap that are no longer being used by the application and performs the necessary operations to reclaim their memory."

                                  So, in your scenario, the garbage collector should release memory allocated by the SpellChecker, OptionsSpelling, and OperationSpellCheck objects when the Form1 form is closed if the application lacks of memory, since these objects are not referenced in your application any longer.

                                  If you faced different behavior, please profile your application with a memory profiler and send us the instance retention graph that demonstrates the problem.
                                  See also: The instance retention graph

                                • Marlene 10.18.2019

                                  I viewed the video you attached several times and saw what you are describing - basically, that spellcheck in the sample app is working as designed.

                                  When *I* run your sample app, it looks to be totally different.  Please look at what I am attaching.  The top picture is your sample app and you running it.  The bottom picture is your sample app and me running it.  I added to my copy also the iteration 10x creating form1.   Why are there so few g arbage collection symbols on my graph?  See how my graph has two jumps up?  One is the first time I clicked button1 and created 10 instances.  Then I closed those 10 and created 10 more and there's another jump and the memory isn't getting freed!  Do you have any input into that???

                                  Do we need to buy ANTS to get to the bottom of this?

                                • Yulia (DevExpress Support) 10.18.2019

                                  As far as I see in your screenshot, only 207 MB of memory is allocated by the application. Try to open and close the Form1 forms several times to make the memory consumption closer to the memory limit for 32-bit processes - 2 GB. Does the garbage collection occur in this case?

                                • Marlene 10.18.2019

                                  Yes, I was wondering why your memory usage started out so high and mine was low.  I launched more forms to use more memory and the memory usage dropped at 2:20.