3

I wrote a piece of code that measures the memory consumption for a method(average memory and peak memory values). I simply run the method in a thread and call the GC.GetTotalMemory(false) in a loop that checks if the thread is still alive and then calculates current memory and adds it to "totalmem" variable to get the average later. Also I call this analyzer in a loop because I need to run it on multiple set of different parameters (measuring consumption in different files for example) so I need to wait till the single thread finishes and collect garbage then start the next analysis. My question is: Is this a bad way and will the output be close to the real one or accurate? Is measuring a single thread memory equals to measuring process memory?

      double totalmem = 0;
      long iterationsCount = 0;
      double PeakMemory = 0;

     var t = new Thread(() =>
        {                
            int output = methodToAnalyze(int a, string b);

            }

            Console.WriteLine("Finished thread");
        });

        t.Start();
        Console.WriteLine("Started thread running");
        while (t.IsAlive)
        {
            var mem = (double)GC.GetTotalMemory(false);

            // convert to MB
            mem = mem / (1024 * 1024);

            totalmem += mem;
            iterationsCount ++;
            if (mem > PeakMemory)
            {
                PeakMemory = mem;
            }
        }

        t.Join();

        var AverageMemory = (totalmem / iterationsCount);
        var ElapsedTimeInMs = elapsedMs;
yomna ali
  • 31
  • 3

1 Answers1

0

I would look into use the System Diagnostics class. You'll have to be careful when you calculate memory usage because depending what garbage is collected your results are going to vary drastically.

Process currentProcess = System.Diagnostics.Process.GetCurrentProcess();
long totalBytesOfMemoryUsed = currentProcess.WorkingSet64;
Sam Marion
  • 690
  • 1
  • 4
  • 17
  • Is there a way to assign the calculation for only the method I want? How can I call it as a process? – yomna ali Aug 30 '17 at 18:09
  • Are you sure your current way of doing it is only calculating it for a single method? According to the documentation is returns the current number of bytes allocated. I'm going to try running a sample app to test. – Sam Marion Aug 30 '17 at 18:15
  • After running some tests I'm sure that the current method will not give you memory usage per thread. I'm not 100 percent sure thats possible but maybe this question can help you with amount of CPU usage each thread uses https://stackoverflow.com/questions/934497/how-can-i-get-cpu-usage-and-or-ram-usage-of-a-thread-in-c-sharp-managed-code – Sam Marion Aug 30 '17 at 18:35
  • You can't get memory usage per thread because memory is shared between all threads in a process. How would the OS know whether you allocated memory in one thread and used it in another. And what would it mean? – Sam Marion Aug 30 '17 at 18:36
  • So are you suggesting that it should be measured like this: `methodToMeasure(); Process currentProcess =System.Diagnostics.Process.GetCurrentProcess(); long totalBytesOfMemoryUsed = currentProcess.WorkingSet64;` – yomna ali Aug 30 '17 at 18:42
  • Well you need to figure out where the best place is to call the method. It can be tricky to figure out since GC will alter the result. Turning off GC is not a good metric imo because it will be used when you are no longer using diagnostics – Sam Marion Aug 30 '17 at 18:46