For a Free Analysis, Call 1 888 534 6919
We love warping Blogengine.net into applications that most people would never dream of. This applies to even some of our larger clients. In the process of pushing Blogengine.net to its limits, we began to see some if the limits of BlogEngine. We also gained a larger appreciation of the open source community since there are some really talented software developers out there that comb through these open source blogging platforms and learn it inside and out. My hat has to go out to Peter Kuhn aka Mister GoodCat of Pitorque Software (www.Pitorque.de). He helped us (through his blog post about memory leaks in BlogEngine.net) resolve a critical problem with one our sites that used BlogEngine.net. Hats off to Peter!
I first saw the problem when I was cruising my task manager (a wonderful hobby of mine) and discovered a whopping memory allocation exceeding 1GB. Now we have some large sites, but this clearly was inching up every time a page was viewed and needed to be dealt with.
As helpful as Task Manager is, knowing that a worker process is out of control is nice but WHICH ONE? Since we use host headers to map many websites to the same IP address, and we had multiple IIS configurations working on the same server, I saw the runaway application but didn't know how to identify which site wwas causing the issue.
First I needed the specific PID number for the worker process (which is hidden by default). By using the "View | Select Columns" menu in Task Manager I was able to check the box that made the PID of the worker application appear:
Now we know that our runaway application is number 3584. Great. As always, I learn by precept and precept so I continued to dig, finding an article online that allowed me to execute a special program that lists the IIS application name of any give worker process (by PID or "Process Identifier").
Now we need to discover which application is causing the problem. Here we identify a highly trafficked website that is causing the issue.
This is a website that has a large amount of traffic, benefitting from a large radio advertising budget and pay per click spend. It appears also that the memory climbs per page view so it will just climb and climb and climb.
Here is where our hero Peter Kuhn comes in. He was able to identify that the open source BlogEngine.net version 1.6.1 platform was not using static constructors properly within the code.
The first issue was the BlogRoll. He identified that "the BlogRollItem.Saved event is hooked up every time the control is created (and never released). To change that, make the constructor static, as well as the BlogRollItem_Saved event handler." (Peter Kuhn, www.Pitorque.de). His fix was to simply make the constructor static and recompile the code:
static Blogroll(){ BlogRollItem.Saved += new EventHandler<SavedEventArgs>(BlogRollItem_Saved);}private static void BlogRollItem_Saved(object sender, SavedEventArgs e){ ..
There is a similar problem in many places within the CodeFormatter class. The following elements needed to be set to Static Constructors:
Widget Zone Memory Leak Issues
Then his open source compatriots delved into a lengthy fix-find-fix-find iteration where they began to dig into the more esoteric implementations of WidgetZones (the box containing replaceable and editable widgets ... normally on the left sidebar). The eventual solution was to "Make the constructor static and change the event handler for the saved event, add a field for the dictionary and change the previous field XML_DOCUMENT to be a property that fetches the document from the dictionary." (Peter Kuhn, www.Pitorque.de)
static WidgetZone(){ WidgetEditBase.Saved += delegate { ReloadAllXml(); };}private static Dictionary<string, XmlDocument> _xmlDocumentByZone = new Dictionary<string, XmlDocument>();private const string DefaultZoneName = "be_WIDGET_ZONE";// For backwards compatibility or if a ZoneName is omitted, provide a default ZoneName.private string _ZoneName = DefaultZoneName; private XmlDocument XML_DOCUMENT{ get { // look up the document by zone name if (_xmlDocumentByZone.ContainsKey(ZoneName)) { return _xmlDocumentByZone[ZoneName]; } return null; }}
"The "RetrieveXml" method now is static and takes a zone name as parameter. The "ReloadAllXml" method is new." (Peter Kuhn, www.Pitorque.de)
private static void ReloadAllXml(){ // simply reload all xml documents when something has changed Dictionary<string, XmlDocument> newDocs = new Dictionary<string, XmlDocument>(); foreach (string zoneName in _xmlDocumentByZone.Keys) { XmlDocument doc = RetrieveXml(zoneName); newDocs.Add(zoneName, doc); } _xmlDocumentByZone = newDocs;}private static XmlDocument RetrieveXml(string zoneName){ WidgetSettings ws = new WidgetSettings(zoneName); ws.SettingsBehavior = new XMLDocumentBehavior(); XmlDocument doc = (XmlDocument)ws.GetSettings(); return doc;}
"During initialization, the document for a zone is added to the caching dictionary if it hasn't been loaded yet": (Peter Kuhn, www.Pitorque.de)
protected override void OnInit(EventArgs e){ if (XML_DOCUMENT == null) { // if there's no document for this zone name yet, load it XmlDocument doc = RetrieveXml(ZoneName); if (_xmlDocumentByZone.ContainsKey(ZoneName)) { _xmlDocumentByZone[ZoneName] = doc; } else { _xmlDocumentByZone.Add(ZoneName, doc); } } base.OnInit(e);}
Great News!
What was the outcome? A stunning decrease in load on our server from this single application of over 95%! I guess I can host a few more websites on this server. Thanks Mr. Kuhn!
For more information on this fix, get it from the source! Visit Peter Kuhn's personal blog at http://www.pitorque.de/MisterGoodcat/post/Fixing-the-memory-leaks-in-BlogEngineNET-1-6-1.aspx and keep tabs on any updates to this fix including a download of the source code file.
Jared Nielsen[email protected]The FUZION Agencywww.FUZION.org
Posted in: BlogEngine.net | Blogs | Software Development | SQL Server
Tags: architecture, best practices, FUZION, FUZION Agency, Jacksonville SEO Expert, Jared Nielsen, SEO Expert Jacksonville, SQL, SQL Performance Tuning, IIS, IIS 7.0, BlogEngine.net, Memory Leak, Task Manager, AppCMD, PID, Worker Process, Blogengine, Blogroll, Code Formatter, WidgetZone, Static Constructors, Peter Kuhn
Jacksonville SEO Expert Jared Nielsen Fixes Memory Leak Issue in BlogEngine.net Version 1.6.1 Jacksonville SEO Expert Jared Nielsen Fixes Memory Leak Issue in BlogEngine.net Version 1.6.1
Name* Required Please choose another name
E-mail*
Country [Not specified] Afghanistan Albania Algeria Argentina Armenia Australia Austria Azerbaijan Bahrain Bangladesh Belarus Belgium Belize Bermuda Bolivarian Republic of Venezuela Bolivia Bosnia and Herzegovina Brazil Brunei Darussalam Bulgaria Cambodia Canada Caribbean Chile Colombia Costa Rica Croatia Czech Republic Denmark Dominican Republic Ecuador Egypt El Salvador Estonia Ethiopia Faroe Islands Finland France Georgia Germany Greece Greenland Guatemala Honduras Hong Kong S.A.R. Hungary Iceland India Indonesia Iran Iraq Ireland Islamic Republic of Pakistan Israel Italy Jamaica Japan Jordan Kazakhstan Kenya Korea Kuwait Kyrgyzstan Lao P.D.R. Latvia Lebanon Libya Liechtenstein Lithuania Luxembourg Macao S.A.R. Macedonia (FYROM) Malaysia Maldives Malta Mexico Mongolia Montenegro Morocco Nepal Netherlands New Zealand Nicaragua Nigeria Norway Oman Panama Paraguay People's Republic of China Peru Philippines Poland Portugal Principality of Monaco Puerto Rico Qatar Republic of the Philippines Romania Russia Rwanda Saudi Arabia Senegal Serbia Serbia and Montenegro (Former) Singapore Slovakia Slovenia South Africa Spain Sri Lanka Sweden Switzerland Syria Taiwan Tajikistan Thailand Trinidad and Tobago Tunisia Turkey Turkmenistan U.A.E. Ukraine United Kingdom United States Uruguay Uzbekistan Vietnam Yemen Zimbabwe
Notify me when new comments are added