locked
Memory leak? RRS feed

  • Question

  • Hi everyone,
    I created some C# code to change rename variable names in my large C# file (file size is near 50 M). I used regular expressions to perform this task. Resulted code looks like this one: 

               //Replace each variable with new name
                foreach (string varname in varNames)
                {
                    string newName = GenerateVariableName();
                    code = Regex.Replace(code, string.Format(@"\b{0}\b", varname), newName);
                    GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
                    GC.WaitForPendingFinalizers();
                    GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
                }
                GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
                GC.WaitForPendingFinalizers();
                GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);


    Variable code contains input C# code as string, it contains up to 50000000 unicode characters, so it should need 2 times more bytes (100 M) to be stored in memory. I performing garbage collection regularly during this operation, that is why I suppose that program should need up to 100 M of memory when this method is finished.
    However, program memory usage grows up to 1,5 G when this code is finished, and memory usage never decreased back to 100 M or even 500 M, even when I write something like this:
                code = null;
                GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);            
                GC.WaitForPendingFinalizers();
                GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);

    So even when I remove resulted generated code, memory never becomes released.
    What is possible cause of such problem?
    Sunday, December 21, 2008 7:48 AM

Answers

  • Hello Vitally

    If GC is not effective for you, play a bit with System.Diagnostics.Process.GetCurrentProcess().MaxWorkingSet and System.Diagnostics.Process.GetCurrentProcess().MinWorkingSet.
    Changing this properties will decrease imediatelly memory consumption.

    Hope this helps :)
    http://www.portadev.com
    • Proposed as answer by Dato0011 Saturday, December 27, 2008 8:25 PM
    • Marked as answer by VASoftOnline Monday, February 2, 2009 8:09 AM
    Saturday, December 27, 2008 8:24 PM

All replies

  • I'd say use a profiler to see what/who is keeping the reference on the data , if you can't afford one this article explains how to do it yourself.
    • Marked as answer by VASoftOnline Sunday, December 21, 2008 12:14 PM
    • Unmarked as answer by VASoftOnline Monday, December 22, 2008 7:53 AM
    Sunday, December 21, 2008 8:05 AM
  •  It is really good article and I was able to decrease memory leak a lot (its  cause was Regex static methods calls caching).
    However, memory leak was not removed fully. I see strange things now.
    1. When I enter !dumpheap -stat I see:
    790fd8c4 8309 160335872 System.String
    Well, it looks like the cause is a lot of not released strings.
    2. I make !dumpheap -mt 790fd8c4
    18011000 790fd8c4 53036360
    3. At last, I make following !gcroot
    !gcroot 18011000
    Note: Roots found on stacks may be false positives. Run "!help gcroot" for
    more info.
    Error during command: Warning. Extension is using a callback which Visual Studio does not implement.
    Scan Thread 3236 OSTHread ca4
    Scan Thread 3816 OSTHread ee8
    Scan Thread 1812 OSTHread 714
    Scan Thread 3888 OSTHread f30

    As I understand, such result means that there are not any references to target string... however, it is never removed when I make GC.Collect() calls...
    What is possible cause?
    Does string.Format method have any caching? The cause of error is supposed to be caching strings by some types like Regex, string.Format, ect. I cleared Regex cache by setting CacheSize to 0, but some strings are still not removed.
    Monday, December 22, 2008 7:48 AM
  • Do you define the "code" variable as global or static? if so, define it as local variable.


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Friday, December 26, 2008 8:22 AM
  • Hello Vitally

    If GC is not effective for you, play a bit with System.Diagnostics.Process.GetCurrentProcess().MaxWorkingSet and System.Diagnostics.Process.GetCurrentProcess().MinWorkingSet.
    Changing this properties will decrease imediatelly memory consumption.

    Hope this helps :)
    http://www.portadev.com
    • Proposed as answer by Dato0011 Saturday, December 27, 2008 8:25 PM
    • Marked as answer by VASoftOnline Monday, February 2, 2009 8:09 AM
    Saturday, December 27, 2008 8:24 PM