D
Daniel Billingsley
Jon Skeet posted some code in another thread using the
GC.GetTotalMemory(true) method as a way to demonstrate the amount of memory
being allocated for a certain data type.
That method was new to me and I thought it looked like a great simple way to
implement some general memory monitoring. So I put a timer on my Mdi parent
form and had it display the results of that call every couple of seconds.
When the results were pretty weird compared to what I expected, I wrote the
following console app. I think I understand why the results do what they do
except:
- Why the big 11k jump when the hog is created? Is that mostly the
MemoryHog class itself?
- Why the jump and not drop when hog is set to null?
Also, if I understand the documentation for passing true in the parameter,
doing so doesn't necessarily guarantee collection of all generations, only
whatever can be done in a preset amount of time. Not that it probably
matters in my scenario, but just for my curiosity.
--------------------
using System;
using System.IO;
namespace JunkConsoleApp
{
public class TestClass
{
public static void Main()
{
long howMuchBefore = 0L;
long howMuchDuring = 0L;
long howMuchAfter = 0L;
long memorybeforeCall = 0L;
long memoryAfterCall = 0L;
howMuchBefore = GC.GetTotalMemory(true);
Console.WriteLine("Memory Before:\t\t{0}", howMuchBefore);
MemoryHog hog = new MemoryHog();
howMuchDuring = GC.GetTotalMemory(true);
Console.WriteLine("Memory with hog:\t{0}", howMuchDuring);
hog = null;
GC.Collect(GC.MaxGeneration); // Just to be absolutely sure!
GC.Collect(GC.MaxGeneration);
howMuchAfter = GC.GetTotalMemory(true);
Console.WriteLine("Memory After:\t\t{0}", howMuchAfter);
Console.WriteLine(new string('-', 50));
memorybeforeCall = GC.GetTotalMemory(true);
Console.WriteLine("TestMethod-Before call: \t{0}", memorybeforeCall);
TestMethod();
memoryAfterCall = GC.GetTotalMemory(true);
Console.WriteLine("TestMethod-After return:\t{0}", memoryAfterCall);
Console.WriteLine(new string('-', 50));
memorybeforeCall = GC.GetTotalMemory(true);
Console.WriteLine("TestMethod-Before call: \t{0}", memorybeforeCall);
TestMethod();
memoryAfterCall = GC.GetTotalMemory(true);
Console.WriteLine("TestMethod-After return:\t{0}", memoryAfterCall);
Console.WriteLine(new string('-', 50));
Console.WriteLine("Press a key");
Console.Read();
}
public static void TestMethod()
{
long memoryAtStart = 0L;
long memoryWithHog = 0L;
memoryAtStart = GC.GetTotalMemory(true);
Console.WriteLine("TestMethod-Start:\t\t\t{0}", memoryAtStart);
MemoryHog hog = new MemoryHog();
memoryWithHog = GC.GetTotalMemory(true);
Console.WriteLine("TestMethod-With hog:\t\t\t{0}", memoryWithHog);
}
}
class MemoryHog
{
private string s1 = "hello";
private string s2 = "hello";
private string s3 = "hello";
private string s4 = "hello";
private string s5 = "hello";
}
} // namespace JunkConsoleApp
GC.GetTotalMemory(true) method as a way to demonstrate the amount of memory
being allocated for a certain data type.
That method was new to me and I thought it looked like a great simple way to
implement some general memory monitoring. So I put a timer on my Mdi parent
form and had it display the results of that call every couple of seconds.
When the results were pretty weird compared to what I expected, I wrote the
following console app. I think I understand why the results do what they do
except:
- Why the big 11k jump when the hog is created? Is that mostly the
MemoryHog class itself?
- Why the jump and not drop when hog is set to null?
Also, if I understand the documentation for passing true in the parameter,
doing so doesn't necessarily guarantee collection of all generations, only
whatever can be done in a preset amount of time. Not that it probably
matters in my scenario, but just for my curiosity.
--------------------
using System;
using System.IO;
namespace JunkConsoleApp
{
public class TestClass
{
public static void Main()
{
long howMuchBefore = 0L;
long howMuchDuring = 0L;
long howMuchAfter = 0L;
long memorybeforeCall = 0L;
long memoryAfterCall = 0L;
howMuchBefore = GC.GetTotalMemory(true);
Console.WriteLine("Memory Before:\t\t{0}", howMuchBefore);
MemoryHog hog = new MemoryHog();
howMuchDuring = GC.GetTotalMemory(true);
Console.WriteLine("Memory with hog:\t{0}", howMuchDuring);
hog = null;
GC.Collect(GC.MaxGeneration); // Just to be absolutely sure!
GC.Collect(GC.MaxGeneration);
howMuchAfter = GC.GetTotalMemory(true);
Console.WriteLine("Memory After:\t\t{0}", howMuchAfter);
Console.WriteLine(new string('-', 50));
memorybeforeCall = GC.GetTotalMemory(true);
Console.WriteLine("TestMethod-Before call: \t{0}", memorybeforeCall);
TestMethod();
memoryAfterCall = GC.GetTotalMemory(true);
Console.WriteLine("TestMethod-After return:\t{0}", memoryAfterCall);
Console.WriteLine(new string('-', 50));
memorybeforeCall = GC.GetTotalMemory(true);
Console.WriteLine("TestMethod-Before call: \t{0}", memorybeforeCall);
TestMethod();
memoryAfterCall = GC.GetTotalMemory(true);
Console.WriteLine("TestMethod-After return:\t{0}", memoryAfterCall);
Console.WriteLine(new string('-', 50));
Console.WriteLine("Press a key");
Console.Read();
}
public static void TestMethod()
{
long memoryAtStart = 0L;
long memoryWithHog = 0L;
memoryAtStart = GC.GetTotalMemory(true);
Console.WriteLine("TestMethod-Start:\t\t\t{0}", memoryAtStart);
MemoryHog hog = new MemoryHog();
memoryWithHog = GC.GetTotalMemory(true);
Console.WriteLine("TestMethod-With hog:\t\t\t{0}", memoryWithHog);
}
}
class MemoryHog
{
private string s1 = "hello";
private string s2 = "hello";
private string s3 = "hello";
private string s4 = "hello";
private string s5 = "hello";
}
} // namespace JunkConsoleApp