I'm trying to get a handle on memory usage of my ASP.NET MVC4 / EF5 web application through dotMemory profiling. I'm still confused by what I see, but one thing that concerns me is the large difference in memory between running a profile on IISExpress and WebDev.
At start up, IISExpress shows (* Actually this jumped each time I killed the process and started up the profiler again):
Total: 352.3 MB
Heap Gen 0: 242.7 MB
Heap Gen 1: 3.1 KB
Heap Gen 2: 31.5 MB
Whereas WebDev:
Total: 180 MB
Heap Gen 0: 3 MB
Heap Gen 1: 148.2 KB
Heap Gen 2: 24.6 MB
This application is hosted on IIS 7.5 so which should I trust? And why does my managed memory go down after a snapshot? This is especially true with IISExpress.
Also I'm having a hard time finding what are real issues I can impact. Things tend to boil down to EF or AutoMapper and I don't see how I can avoid iterator allocation in entity linq queries and CreateMaps, etc. (http://blog.jetbrains.com/dotnet/2014/07/24/unusual-ways-of-boosting-up-app-performance-lambdas-and-linqs/)
What am I not seeing?
Edit
Memory Traffic snapshot -- String is the largest consumer
Lots of byte allocated from using AutoMapper's CreateMap -- any possible remedy?
Heap Gen 0: 242.7 MB
This is a specific thing of IIS to have a very huge Gen 0 heaps
And why does my managed memory go down after a snapshot? This is especially true with IISExpress.
dotMemory forces garbage collecting on getting snapshot (this is how MS profiling API works)
Also I'm having a hard time finding what are real issues I can impact.
I would recommend to check if a picture of the memory consumption correlates with a picture "in your head". Check top 5-10 types which objects consumes the greatest amount of the memory. Look at top objects exclusively retains memory. Check an app on memory leaks - all objects are released after a particular activity finishes.
If you don't see any very unusual, maybe you do not have to do anything.
Related
I am having a bit of trouble trying to find some unmanaged memory allocation from a .dmp file.
I have been trying to follow the tips - here but I am hitting a bit of a wall
!address -summary gives me the below which shows the MEM_COMMIT is at 1.030Gb which is expected (please ignore the TB of memory, this is probably due to the fact this is from a virtual web server)
!eeheap -gc gives me the below which shows the .net memory usage is 150MB (if I run !eeheap on it's own I do not see any extra heaps, I still see 8 GC heaps that total 150MB)
This leads me to believe the majority of the memory usage is coming from unmanaged memory
The instructions I have been following then say to use !heap -s to find where the unmanaged memory is. When I do that I see the below
Now I would expect to see a large amount of memory being used by a heap that I could further analyse to try and locate the unmanaged memory, but I do not see any heaps that come close to filling showing the 1GB of used memory
I did notice that !address -summary showed 600MB in PAGE_READWRITE, so I tried !address /f:PAGE_READWRITE which I hoped would give me something else to go on, but it gives me a list of memory used by PAGE_READWRITE and Im not too sure how to analyse any further
Basically I want to know where the difference in memory between 1GB and 150MB of .net allocated memory is being used
Any help would be great
In "Usage Summary", you can see
<unknown> 17 GB
Heap 235 MB
<unknown> can be .NET or memory directly allocated by VirtualAlloc(). IMHO, someone using VirtualAlloc() directly is quite rare.
Heap is memory allocated via the Heap manager. So, !heap -s will not show more than 235 MB.
MEM_COMMIT is just another state of memory and it can be in any of the usage states. To find the 1 GB of committed memory, you need to sum up everything you have:
154 MB used by .NET GC Heaps
235 MB used by Heaps
234 MB used by Images
up to 50 MB in Stacks
... some smaller parts not really relevant
This already explains 620 to 670 MB of memory, depending on how much of the stack memory was actually committed.
If you execute !eeheap without the -gc parameter, you'll see that there is more memory used by .NET since it also has LoaderHeaps, JIT Heaps, domain heaps etc.
I developed a J2ME application for s60 device. I used the memory monitor of sun wireless toolkit
to monitor memory size consumed during the execution of my application. I found that
memory size consumed reaches 126 KB. I wanted to know what is the standard memory size
consumed by J2ME applications? In other words, what is the optimum or acceptable memory size consumed
by the execution of J2ME applications. In order to compare and evaluate my application's
memory consumption according to standards.
I do not think there are any standards concerning memory consumption. Memory consumption depends on the nature of the app and amount of data it works with. There are too major concerns regarding memory - running of out it and/or too much GC activity (too frequent and/or taking too much time).
Given the fact that heap size is typically at least 1 MB on non-smartphones, and on S60 heap size is limited only by free memory, then with your 126 kB (top consumption as you say) you are more than fine and quite far from OutOfMemoryError :), and I guess there is also low GC activity because only a small part of heap is used and thus there is little pressure to run gc...
My app has been crashing a lot, for reasons that I'm struggling to understand. It's not so much that it's crashing -- it's getting killed by an outside "Unknown" process:
Processes
Name <UUID> rpages recent_max [reason] (state)
test-app <....> 167111 167111 [per-process-limit] (frontmost) (resume)
I could understand that if I were allocating a huge block of memory, or a zillion smaller blocks, but I'm not doing anything that outrageous. Profiling with Instruments tells me that the app uses only around 8 MB, occasionally spiking up to 13 MB or so when I load some large content. There are no egregious leaks, and the app is often killed very quickly.
A colleague started using Activity Monitory to check the app's memory usage while running in the simulator and noticed that memory spiked from around 70 MB (I guess things are a little different in the simulator) to upward of 800 MB when we start using a certain library. So, I started profiling in the simulator instead of on the device. The Allocations tool continues to report that the app uses 8-ish MB, but the VM Tracker tells another story:
So... it looks like VM Tracker is able to see some significant memory use that Allocations isn't.
Why is the Allocations tool missing 99% of the memory this app is using?
Update: In response to nielsbot's question, I took a closer look at the VM Tracker's info and found that the largest part of the memory that I'm not seeing in Allocations is attributed to Core Animation:
I think VM space includes things like shared frameworks and mapped memory whereas allocations may not...
I guess resident size is closer to the actual amount of RAM used. Pure VM memory could just be mapped address space, not actual physical RAM consumed.
For example, looking at Safari, I see 1.92 GB virtual memory mapped, but closer to 549 MB resident, which I think makes sense...
I have an application that loads 170 files (let’s say they are text files) from disk in individual objects and kept in memory all the time. The memory is allocated once when I load those files from disk. So, there is no memory fragmentation involved. I also use FastMM to make sure my applications never leaks memory.
The application compares all these files with each other to find similarities. Over-simplified we can say that we compare text strings but the algorithm is way more complex as I have to allow some differences between strings. Each file is about 300KB. Loaded in memory (the object that holds it) it takes about 0.4MB of RAM. So, the running app takes about 60MB or RAM (working set). It processes the data for about 15 minutes. The thing is that it generates over 40 million page faults.
Why? I have about 2GB of free RAM. From what I know Page Faults are slow. How much they are slowing down my program?
How can I optimize the program to reduce these page faults? I guess it has something to do with data locality. Does anybody know some example algorithms for this (Delphi)?
Update:
But looking at the number of page faults (no other application in Task Manager comes close to mine, not even by far) I guess that I could increase the speed of my application IF I manage to optimize memory layout (reduce the page faults).
Delphi 7, Win 7 32 bit, RAM 4GB (3GB visible, 2GB free).
Caveat - I'm only addressing the page faulting issue.
I cannot be sure but have you considered using Memory Mapped files? In this way windows will use the files themselves as the paging file (rather than the main paging file pagrefile.sys). If the files are read only then the number of page faults should theoretically decrease as the pages won't need to written out to disk via the paging file as windows will just load the data from the file itself as needed.
Now to reduce files from paging in and out you need to try and go through the data in one direction so that as new data is read, older pages can be discarded for ever. Here is where you trade off going over the files again and caching data - the cache has to be stored somewhere.
Note that Memory Mapped files is how windows loads .dlls and .exes amongst other things. I've used them to scan though gigabyte files without hitting memory limits (we had MBs in those days and not GBs of ram).
However from the data you describe I'd suggest the ability to not go back ovver files will reduce the amount of repaging going on.
On my machine most pagefaults are reported for developer studio which is reported to have 4M page faults after 30+ minutes total CPU time. You get 10 times more, in half the time. And memory is scarce on my system. So 40M faults seems like a lot.
It could just maybe be you have a memory leak.
the working set is only the physical memory in use for your application. If you leak memory, and don't touch it, it will get paged out. You will see the virtual memory useage (or page file use) increase. These pages might be swapped back in when the heap memory walks the heap, to get swapped out again by windows.
Because you have a lot of RAM, the swapped out pages will stay in physical memory, as nobody else needs them. (a page recovered from RAM counts as a soft fault, from disk as a hard one)
Do you use an exponential resize system ?
If you grow the block of memory in too small increments while loading, it might constantly request large blocks from the system, copy the data over, and then release the old block (assuming that fastmm (de)allocates very large blocks directly from the OS).
Maybe somehow this causes a loop where the OS releases memory from your app's process, and then adds it again, causing page faults on first write.
Also avoid Tstringlist.load* methods for very large files, IIRC these consume twice the space needed.
In my Windows XP Task Manager, some processes display a higher value in the Mem Usage column than the VMSize. My Firefox instance, for example shows 111544 K as mem usage and 100576 K as VMSize.
According to the help file of Task Manager Mem Usage is the working set of the process and VMSize is the committed memory in the Virtual address space.
My question is, if the number of committed pages for a process is A and the number of pages in physical memory for the same process is B, shouldn't it always be B ≤ A? Isn't the number of pages in physical memory per process a subset of the committed pages?
Or is this something to do with sharing of memory among processes? Please explain. (Perhaps my definition of 'Working Set' is off the mark).
Thanks.
Virtual Memory
Assume that your program (eg Oracle) allocated 100 MB of memory upon startup - your VM size goes up by 100 MB though no additional physical / disk pages are touched. ie VM is nothing but memory book keeping.
The total available physical memory + paging file memory is the maximum memory that ALL the processes in the system can allocate. The system does this so that it can ensure that at any point time if the processes actually start consuming all that memory it allocated the OS can supply the actual physical pages required.
Private Memory
If the program copies 10 MB of data into that 100 MB, OS senses that no pages have been allocated to the process corresponding to those addresses and assigns 10 MB worth of physical pages into your process's private memory. (This process is called page fault)
Working Set
Definition : Working set is the set of memory pages that have been recently touched by a program.
At this point these 10 pages are added to the working set of the process. If the process then goes and copies this data into another 10 MB cache previously allocated, everything else remains the same but the Working Set goes up again by 10 Mb if those old pages where not in the working set. But if those pages where already in the working set, then everything is good and the programs working set remains the same.
Working Set behaviour
Imagine your process never touches the first 10 pages ever again, in which case these pages are trimmed off from your process's working set and possibly sent to the page file so that the OS can bring in other pages that are more frequently used. However if there are no urgent low memory requirements, then this act of paging need not be done and OS can act as if its rich in memory. In this case the working set simply lets these pages remain.
When is Working Set > Virtual Memory
Now imagine the same program de-allocates all the 100 Mb of memory. The programs VM size is immediately reduced by 100 MB (remember VM = book keeping of all memory allocation requests)
The working set need not be affected by this, since that doesn't change the fact that those 10 Mb worth of pages where recently touched. Therefore those pages still remain in the working set of the process though the OS can reclaim them whenever it requires.
This would effectively make the VM < working set. However this will rectify if you start another process that consumes more memory and the working set pages are reclaimed by the OS.
XP's Task Manager is simply wrong. EDIT: If you don't believe me (and someone doesn't, because they voted this down), read Firefox 3 Memory Usage. I quote:
If you’re looking at Memory Usage
under Windows XP, your numbers aren’t
going to be so great. The reason:
Microsoft changed the meaning of
“private bytes” between XP and Vista
(for the better).
Sounds like MS got confused. You only change something like that if it's broken.
Try Process Explorer instead. What Task Manager labels "VM Size", Process Explorer (more correctly) labels "Private Bytes". And in Process Explorer, Working Set (and Private Bytes) are always less than or equal to Virtual Size, as you would expect.
File mapping
Very common way how Mem Usage can be higher than VM Size is by using file mapping objects (hence it can be related to shared memory, as file mapping is used to share memory). With file mapping you can have a memory which is committed (either in page file or in physical memory, you do not know), but has no virtual address assigned to it. The committed memory appears in Mem Usage, while used virtual addresses usage is tracked by VM Size.
See also:
What does “VM Size” mean in the Windows Task Manager? on Stackoverflow
Breaking the 32 bit Barrier in my developer blog
Usenet discussion Still confused why working set larger than virtual memory
Memory usage is the amount of electronic memory currently allocated to the process.
VM Size is the amount of virtual memory currently allocated to the process.
so ...
A page that exists only electronically will increase only Memory Usage.
A page that exists only on disk will increase only VM Size.
A page that exists both in memory and on disk will increase both.
Some examples to illustrate:
Currently on my machine, iexplore has 16,000K Memory Usage and 194,916 VM Size. This means that most of the memory used by Internet Explorer is idle and has been swapped out to disk, and only a fraction is being kept in main memory.
Contrast with mcshield.exe with has 98,984K memory usage and 98,168K VM Size. My conclusion here is that McAfee AntiVirus is active, with at lot of memory in use. Since it's been running for quite some time (all day, since booting), I expect that most of the 98,168K VM Size is copies of the electronic memory - though there's nothing in Task Manager to confirm this.
You might find some explaination in The Memory Shell Game
Working Set (A) – This is a set of virtual memory pages (that are committed) for a process and are located in physical RAM. These pages fully belong to the process. A working set is like a "currently/recently working on these pages" list.
Virtual Memory – This is a memory that an operating system can address. Regardless of the amount of physical RAM or hard drive space, this number is limited by your processor architecture.
Committed Memory – When an application touches a virtual memory page (reads/write/programmatically commits) the page becomes a committed page. It is now backed by a physical memory page. This will usually be a physical RAM page, but could eventually be a page in the page file on the hard disk, or it could be a page in a memory mapped file on the hard disk. The memory manager handles the translations from the virtual memory page to the physical page. A virtual page could be in located in physical RAM, while the page next to it could be on the hard drive in the page file.
BUT: PF (Page File) Usage - This is the total number of committed pages on the system. It does not tell you how many are actually written to the page file. It only tells you how much of the page file would be used if all committed pages had to be written out to the page file at the same time.
Hence B > A...
If we agree that B represents "mem usage" or also PF usage, the problem comes from the fact it actually represents potential page usages: in Xp, this potential file space can be used as a place to assign those virtual memory pages that programs have asked for, but never brought into use...
Memory fragmentation is probably the reason:
If the process allocates 1 octet, it counts for 1 octet in the VMSize, but this 1 octet requires a physical page (4K on windows operating system).
If after allocating/freeing memory, the process has a second octet that is separated by more than 4K from the first one, this second octet will always be stored on a separate physical page than the 1 one.
So the VM Size count is 2 octets but the Memory Usage is 2 pages== 8K
So the fact that MemUsage is greater than VMSize shows that process does a lot of allocation and deallocation and fragments the memory.
This could be because the process is started a long time ago.
Or else there is place for optimization ;-)