Global.asax has to be threaded as dynamic content sense a soft-resert of an ASP.NET site. So the Application_start method is going to be accessed each time this happen on the site (some one change web.config or drop a file that triggers a soft-reset).
Environment: Windows 2008 64 bit, IIS 7.5, .NET 3.5
With Windbg
w3wp.dmp
Examine all objects named "global_asax"
0:000>!dumpheap -type global_asax
Statistics:
MT Count TotalSize Class Name
000007ff005bf698 225 9720 ASP.global_asax
Total 225 objects
Examine one of the method table objects
0:000> !dumpheap -mt 000007ff005bf698
------------------------------
Heap 0
Address MT Size
00000000ff9eb270 000007ff005bf698 216
total 1 objects
0:000> !objsize 00000000ff9eb270
sizeof(00000000ff9eb270) = 2990144 ( 0x2da040) bytes (ASP.global_asax)
Calculation
225 not garbage collected old Global.asax allocating 657 Mb of memory
225 * 2990144 ~ 657 MB
Solution
Examine the code in our Global.asax there is the failing code
EPiServer.DataFactory.SavedPage += SavePageEvent;
Sense Data factory is an instance that never expires it should be threaded as a static class, and when you attach events from dynamic content to static content the dynamic content can’t be garbage collected and will be left in memory.