• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 844
  • Last Modified:

View ASP.NET User Control Output Cache

Hello,

We have an ASP.NET website running on IIS 7.0, .NET v4.0 Integrated app pool, Windows Server 2008 x64.

The w3wp.exe service uses approximately 4,700,000K of memory and we're looking to trim it down.

We heavily use User Controls (.ascx files), and often cache many of them, such as:

<%@ OutputCache Duration="28800" VaryByParam="id" %>

We are trying to inspect our cache, to determine how many user controls are in our cache, and of which types.

The following code isn't getting us there:

<%@ Page Language="C#" %>

<%
	System.Web.Caching.Cache cache = HttpRuntime.Cache;
	Response.Write(string.Format("Cache Count: {0}<br />", cache.Count));
	Response.Write(string.Format("EffectivePrivateBytesLimit: {0}<br />", cache.EffectivePrivateBytesLimit));
	Response.Write(string.Format("EffectivePercentagePhysicalMemoryLimit: {0}<br />", cache.EffectivePercentagePhysicalMemoryLimit));
%>

Open in new window


Cache Count: 0
EffectivePrivateBytesLimit: 5149770547
EffectivePercentagePhysicalMemoryLimit: 99

We weren't expecting to see a cache count of 0.

Are the cached user controls accessible?  We would like to see the total count and enumerate through them, but can't find them.

We might be able to alleviate our memory issues by simply changing the caching/cache/privateBytesLimit and letting it scavenge, but would much rather trim the fat first if we had a clearer picture of our most heavily cached controls.

Thanks,
0
epicdevelopers
Asked:
epicdevelopers
  • 3
  • 2
1 Solution
 
StephanLead Software EngineerCommented:
I don't think you can create over 4gb on outputcache. Maybe there is something in the code that causes a leak. End the w3wp process and keep the process list open and walk through the site. See if there is any page that causes a huge increasement on the memory usage of the process.
0
 
epicdevelopersAuthor Commented:
Sorry but not really the answer we are looking for -- specifically we would like to know the API syntax for viewing the objects contained within the user control output cache.  I have found many articles on how to put objects in the cache yourself, with policies, expiration, caching keys, etc -- but I would like to know how to view the ones that are being managed by ASP.NET.

Thanks,
0
 
StephanLead Software EngineerCommented:
As far I know, there is no way to see the outputcache from HttpRuntime.Cache directly.
I have found this on the net, maybe this way you can enumerate through the data using reflection since it needs to be internal:

Type runtimeType = typeof(HttpRuntime);

            PropertyInfo ci = runtimeType.GetProperty(
               "CacheInternal",
               BindingFlags.NonPublic | BindingFlags.Static);

            Object cache = ci.GetValue(ci, new object[0]);

            FieldInfo cachesInfo = cache.GetType().GetField(
                "_caches",
                BindingFlags.NonPublic | BindingFlags.Instance);
            object cacheEntries = cachesInfo.GetValue(cache);

            List<object> outputCacheEntries = new List<object>();

            foreach (Object singleCache in cacheEntries as Array)
            {
                FieldInfo singleCacheInfo =
                singleCache.GetType().GetField("_entries",
                   BindingFlags.NonPublic | BindingFlags.Instance);
                object entries = singleCacheInfo.GetValue(singleCache);

                foreach (DictionaryEntry cacheEntry in entries as Hashtable)
                {
                    FieldInfo cacheEntryInfo = cacheEntry.Value.GetType().GetField("_value",
                       BindingFlags.NonPublic | BindingFlags.Instance);
                    object value = cacheEntryInfo.GetValue(cacheEntry.Value);
                    if (value.GetType().Name == "CachedRawResponse")
                    {
                        outputCacheEntries.Add(value);
                    }
                }
            }

            foreach (var item in outputCacheEntries)
            {
                Response.Write(item.ToString() + "<br />");
            }

Open in new window

0
 
epicdevelopersAuthor Commented:
This shows me a single System.Web.Caching.CachedRawResponse (when HttpRuntime.Cache.Count == 1) -- this is one of the few actual pages we cache, but no PartialCachingControl classes, which is what I think I'm looking for, the cached user controls.
0
 
epicdevelopersAuthor Commented:
Actually on second thought this does get it close to where we want to be -- there are System.Web.UI.BasePartialCachingControl+PartialCachingCacheEntry entries that aren't quite what we were hoping for, but there may be enough "OutputString" info to manually determine which user controls the PartialCachingCacheEntry  elements represent.  We'll keep looking into it but I think we have enough to go from now.

            foreach (Object singleCache in cacheEntries as Array)
            {
                FieldInfo singleCacheInfo =
                singleCache.GetType().GetField("_entries",
                   BindingFlags.NonPublic | BindingFlags.Instance);
                object entries = singleCacheInfo.GetValue(singleCache);

                foreach (DictionaryEntry cacheEntry in entries as Hashtable)
                {
                    FieldInfo cacheEntryInfo = cacheEntry.Value.GetType().GetField("_value",
                       BindingFlags.NonPublic | BindingFlags.Instance);
                    object value = cacheEntryInfo.GetValue(cacheEntry.Value);
                        outputCacheEntries.Add(value);
                }
            }

            foreach (object item in outputCacheEntries)
            {
                Response.Write(item.ToString() + "<br />");
                foreach (FieldInfo finfo in item.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance))
                {
                	Response.Write(string.Format("&nbsp;&nbsp;{0} = {1}<br />", finfo.Name, finfo.GetValue(item)));
                }
            }

Open in new window

0

Featured Post

How to Use the Help Bell

Need to boost the visibility of your question for solutions? Use the Experts Exchange Help Bell to confirm priority levels and contact subject-matter experts for question attention.  Check out this how-to article for more information.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now