3

I'm trying to measure memory usage of a code, but i don't know how to proceed. I don't want to use "DotMemory" or any "profiler" i need to do it by programming.

There is any way to know how much object was allocated ? Like 5 int(4 bytes) + 4 Object (16 bytes) ...

I used

process.WorkingSet64

but every time I run the same code I get different values.

So what is the best way to measure memory usage of a code ?

gp.
  • 8,074
  • 3
  • 38
  • 39
omega
  • 41
  • 1
  • 6
  • 3
    There´s a good reason why profiling-tools such as DotMemory cost money as collecting the total amount of memory reserved is lot more than just counting any objects footprint within your program. There´s also some amount of memory reserved for .NET self which is considered in the workingset. – MakePeaceGreatAgain Jul 10 '15 at 11:40
  • but why if i run the same code even if i use DotMemory or CLRprolfiler the allocation size is different ? – omega Jul 10 '15 at 11:42
  • 1
    possible duplicate of [How to measure the total memory consumption of the current process programatically in .NET?](http://stackoverflow.com/questions/2342023/how-to-measure-the-total-memory-consumption-of-the-current-process-programatical) – Pavel K Jul 10 '15 at 11:43
  • 2
    Because as already mentioned the WorkingSet also represents the memory used by .NET itself. – MakePeaceGreatAgain Jul 10 '15 at 11:43
  • 2
    it's different because the value includes also system libraries, not only the part of code is working – hazjack Jul 10 '15 at 12:03
  • @hazjack So How i can mesure the memory usage jut for code working and not including other stuff – omega Jul 10 '15 at 12:13
  • You use a tool built by people that know how these things work, like DotMemory or any other profiler. – Lasse V. Karlsen Jul 10 '15 at 12:34

4 Answers4

2

.NET is a managed memory environment. This means that allocation and deallocation is handled transparently for you, but it also means that the memory usage patterns aren't entirely deterministic.

99.9% of the time, this isn't an issue at all. The rest of the time, you should focus your work on the area that matters - usually, it's pretty easy to handle all the critical load in one place.

Your question suggests you come from a C/Pascal background - the tradeoff of managed memory is that you shoudln't really care about memory - sure, you want to pay attention not to outright waste memory, but taking twice as much memory as strictly necessary usually isn't a thing to lose sleep about. "Memory before" and "memory after" is a question that really doesn't make much sense in a multi-threaded environment - your method isn't the only one that's running in the meantime.

Luaan
  • 62,244
  • 7
  • 97
  • 116
  • But If i want to know how much object is created for a code like in the methodX() i want to know that 5 Int (size 10bytes) + + 4 Object (16 bytes) .. and so one their any way to do it like using reflection or other thing ? – omega Jul 10 '15 at 11:59
  • @omega Only the debugger really has access to this. And of course, you can't implement the profiler/debugger interfaces from a .NET application. If you're investigating a memory issue, just use CLRProfiler. If you need realtime memory information *in the application itself*, you're doing something seriously wrong. This isn't C/Pascal, you *shouldn't* be monitoring memory all the time. It just isn't your job anymore - outside of profiling. – Luaan Jul 10 '15 at 14:43
2

If you need to measure a memory consumption programmatically you can use dotMemory Unit Current version can be used with unit tests via ReSharper unit test runner, but soon the next version with standalone runner will be available.

var mcp1 = dotMemory.Check();
methodX();
dotMemory.Check(memory =>
{
  var newObjects = memory.GetDifference(mcp1).GetNewObjects();
  var createdObjectsCount = newObjects.ObjectsCount;
  var allocatedMemory = newObjects.SizeInBytes;
});

More details in the blog post.

UPDATE: standalone runner goes EAP https://www.nuget.org/packages/JetBrains.DotMemoryUnit/2.0.20150727.161305-EAP5

Ed Pavlov
  • 2,353
  • 2
  • 19
  • 25
0

Simple and silly:

long total = GC.GetTotalMemory(true);
Alexander Petrov
  • 13,457
  • 2
  • 20
  • 49
  • This doesn't show us the memory used by a specific part of the code. – wingerse Jul 10 '15 at 12:04
  • 2
    @EmpereurAiman Original question have no such requirement. In addition, we can call this method, then execute part of code, then call the method again. The difference is the memory consumption of this part of the code. – Alexander Petrov Jul 10 '15 at 12:18
0

As described by the other postsyou cant just look at the number you see in the process explorer.

If you really want to measure MemoryUsage it is recommandable to use appropriate tools, like RedGate Ants Profler or dotMemory. There are a lot more, but with these two i have made good experiences. They also show you how many instances of each type an in ram and what do hold them alive

List of all instances

The main question is what is the reason you looking on this ? Do you have a RAM Issue ? Perhaps a leak ? When searching an issue the common approach is to make snapshots with tools like mentioned above and compare them. There you can see wether you have a growing number of instances.

To get approximations of objects and their size (for example to see wether you may get problems) you can try to calculate an estimation see this find size of object instanc in bytes in c sharp for example

Community
  • 1
  • 1
Boas Enkler
  • 12,264
  • 16
  • 69
  • 143
  • Wouldn't that be the equivalent of using a profiler (as the OP did not want to use)? – BIBD Jul 10 '15 at 20:29
  • @boas the reason of that is to make unit memory testing like each time we must be sure that the code consume the same memory to decide if the code is okey or not ? – omega Jul 13 '15 at 15:49