WebSync Method Containers and Memory Usage
by Anton Venema, on June 22, 2010
With WebSync Server 3.0.2, we've introduced the targedScan web.config attribute and the WebSyncMethodContainer assembly-level attribute. Together, they can help to reduce memory consumption significantly. This is especially important for shared hosting environments, but is a good practice for any production system.
Before explaining what the new attributes do, let's first look at why memory consumption is an issue at all.
WebSync lets you decorate methods with attributes so they attach to specific server-side events (BeforePublish, AfterSubscribe, etc.). This ability is what makes WebSync so extensible and part of what makes it so easy to use. In order for WebSync to invoke the methods, though, it first has to find them. To do that, WebSync scans the currently loaded assemblies, looking at each type and checking for methods that are decorated with WebSyncEvent or WebSyncScriptModifier. This scan happens just one time, at first run, after which the decorated method information is cached and can be accessed later as needed.
So what's the problem?
Well, there's one small catch. Reflection is expensive, and the .NET framework architects made a design decision a long time ago that any reflective calls for metadata should be cached internally rather than allowing developers to implement caching solutions themselves. This means that whenever type or method information is accessed, the metadata is cached permanently in the application domain. The intention of the architects was to ensure that the reflective work was only every performed once, but for server environments with scarce resources, this is a problem.
As WebSync scans the assemblies/types/methods, .NET caches every piece of information. The internal .NET bloat can be noticeable, even upwards of 100MB memory consumption. We think you would agree, the memory could definitely be put to better use.
Enter the targetedScan and WebSyncMethodContainer attributes, which define where and how to scan.
If targetedScan is set to true in web.config (WebSync/server[targetedScan]), WebSync will ONLY analyze types that are explicitly specified by the WebSyncMethodContainer assembly-level attribute.
For example, if your WebSyncEvent methods are defined in a class called MyWebSyncEvents, simply place the following attribute in AssemblyInfo.cs (in your Properties folder):
Now, if targetedScan is set to true, WebSync will restrict its scan to just that type and its methods, ignoring all other types/methods and thereby preventing their metadata from being cached by .NET.
(Note: WebSyncMethodContainer can be defined multiple times per assembly, once for each type containing WebSync methods.)
We highly recommend that you use this approach, especially in production systems and reusable extension class libraries. There is no reason to have unnecessary memory consumption, especially when that memory could be used to increase concurrency :)