Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

excessive memory usage by iis application pool with umbraco

We have an umbraco 4.11 instance with around 400 nodes, running on iis 7.5, .net 4, windows 2008 r2. upon first visit it consumes around 500mb of ram and moves up to around 900mb. Since the site is going to be deployed on a shared hosting, this would cause us massive problem.

I've tried tracing the custom codes for memory leaks, and found nothing. I Also ran Windbg on the app pool memory dump only to find the following report:

--- Usage Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal    
Free                                    461      7fb`9ab99000 (   7.983 Tb)           99.79%    
<unknown>                              1201        4`4ec32000 (  17.231 Gb)  98.00%    0.21%    
Image                                  2604        0`1123e000 ( 274.242 Mb)   1.52%    0.00%    
Heap                                     74        0`037c2000 (  55.758 Mb)   0.31%    0.00%    
Stack                                   172        0`01c00000 (  28.000 Mb)   0.16%    0.00%    
Other                                     9        0`001b2000 (   1.695 Mb)   0.01%    0.00%    
TEB                                      57        0`00072000 ( 456.000 kb)   0.00%    0.00%    
PEB                                       1        0`00001000 (   4.000 kb)   0.00%    0.00%

--- Type Summary (for busy) ------ RgnCount ----------- Total Size -------- %ofBusy %ofTotal    
MEM_PRIVATE                             628        4`50cda000 (  17.263 Gb)  98.18%    0.21%    
MEM_IMAGE                              3453        0`135fc000 ( 309.984 Mb)   1.72%    0.00%    
MEM_MAPPED                               37        0`01181000 (  17.504 Mb)   0.10%    0.00%   

--- State Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal    
MEM_FREE                                461      7fb`9ab99000 (   7.983 Tb)           99.79%    
MEM_RESERVE                             985        4`226fb000 (  16.538 Gb)  94.06%    0.20%    
MEM_COMMIT                             3133        0`42d5c000 (   1.044 Gb)   5.94%    0.01%

--- Protect Summary (for commit) - RgnCount ----------- Total Size -------- %ofBusy %ofTotal    
PAGE_READWRITE                          881        0`2edd3000 ( 749.824 Mb)   4.16%    0.01%    
PAGE_EXECUTE_READ                       406        0`0f016000 ( 240.086 Mb)   1.33%    0.00%    
PAGE_READONLY                          1157        0`02c1a000 (  44.102 Mb)   0.24%    0.00%    
PAGE_WRITECOPY                          422        0`01cde000 (  28.867 Mb)   0.16%    0.00%    
PAGE_EXECUTE_READWRITE                  121        0`00328000 (   3.156 Mb)   0.02%    0.00%    
PAGE_EXECUTE_WRITECOPY                   89        0`0026e000 (   2.430 Mb)   0.01%    0.00%    
PAGE_READWRITE|PAGE_GUARD                57        0`000e5000 ( 916.000 kb)   0.00%    0.00%

--- Largest Region by Usage ----------- Base Address -------- Region Size ----------
Free                                      5`3f530000      7f9`54ca0000 (   7.974 Tb)
<unknown>                                 2`835b4000        0`7bf7c000 (   1.937 Gb)
Image                                   7fe`e79da000        0`01338000 (  19.219 Mb)
Heap                                      0`0c5e0000        0`00961000 (   9.379 Mb)
Stack                                     0`00960000        0`0007b000 ( 492.000 kb)
Other                                     0`006b0000        0`00181000 (   1.504 Mb)
TEB                                     7ff`ffe90000        0`00002000 (   8.000 kb)
PEB                                     7ff`fffdb000        0`00001000 (   4.000 kb)

the other reports about managed portions of memory are ommitted because they don't show anything out of the ordinary. the dump shows that region or the unmanaged portion is consuming the most memory, which is an indication of win32 api calls or something else I don't know about. What I need to know is if this memory usage is usual? if not what are the causes and fixes that can be applied on it? I'd appreciate any help to clear this issue! 0

like image 208
dannni_mo Avatar asked Aug 03 '13 05:08

dannni_mo


1 Answers

As Eric Herlitz points out in his answer there are many things going on under the hood of an Umbraco installation. In a nutshell, 400 nodes shouldn't cause too much of an issue, as they are published as XML and then cached. Also, a standard Umbraco installation isn't that resource hungry, so there is almost certainly something else at play, and probably quite basic. So check the following:

How are you accessing node content? The most basic mistake that can be made is using the Umbraco API to access node content when you don't need to. For read-only scenarios where you only need published data (e.g. displaying content in the published website) you should use the methods that query the published data in the XML cache. In 4.11.x this would be the umbraco.NodeFactory.Node, INode or DynamicNode via the DynamicNodeContext model passed to a macro. You should avoid using the Document, Content objects etc. as these make calls to the database.

How are you accessing media? Since 4.8, all media saved in the CMS is indexed in the same way nodes are. In 4.7, you would use new Media(id) to retrieve a file in the media library. This hits the database and is therefore very expensive per request. You should use new DynamicMedia(id) as this retrieves the file information from the index and is very quick and makes a substantial difference.

Are you caching macros? Careful use of this feature can help massively. Even calls to the XML cache have a footprint and things like rendering the main navigation of a site can be quite expensive. I tend to cache complex navigation macros like this that are repeated throughout the site. Yes, the will still cause a hit on first request, but they won't subsequently. If you have limited resources however, don't go nuts with the macro caching. Be selective and consider which pages get the most traffic and which have the more complex node traversal queries.

What data are you storing in your document types? You shouldn't really have to review this but it's worth a check especially if you are concious of your site growing in size. If you use the multi-node picker, do you store the XML or the CSV? The CSV is substantially smaller as it only stores the IDs of the nodes. Storing XML is useful for structured data and for accessing using XSLT, but redundant if you are only pulling out the ID of media or content nodes. Do you also have additional fields that aren't used? These will get published to the XML and can save you resources as the XML grows. More fields also means more trips to the database when nodes are saved and published. So less is better.

Are you storing data that doesn't need to be? There is a tendency to make everything CMS-editable. A LinkedIn URL, Twitter ID, company phone number, payment gateway callback pages etc. But realistically, things like this don't change very often if at all. These can safely be relegated to keys in the AppSettings module of the web.config file. And then accessed via static "ConfigConstants" class that makes the keys read-only. This saves a bit of space in the XML cache and lightens the load of saving and publishing pages. It also means that you don't have to query the XML cache for the data.

Do you have an intermediary querying layer and/or extension methods? This is by no means necessary but I like to have extension methods that prevent repetition of code use through the UI. This means that I can always be sure that when I query for a media item, boolean property, root node, etc. I am using the same code each time. I can also perform a little extra caching at this point. So if I had a "Site Settings" node, I could cache the properties of this in an custom lightweight object, so that I didn't have to query for the "Site Settings" node and then its properties each time I needed to access the site-wide data like an address, phone number, URL etc.

Hope this helps a little.

like image 51
Digbyswift Avatar answered Oct 14 '22 19:10

Digbyswift