SPLimitedWebPartManager Memory Leak?
Posted on 05. Jun, 2007 by bryan in SharePoint
Have a look at the following code segment:
while(true) { using (SPSite siteCollection = new SPSite("http://localhost")) using (SPWeb site = siteCollection.OpenWeb("/Marketing")) { SPFolder pagesFolder = site.GetFolder("Pages"); foreach (SPFile page in pagesFolder.Files) { WL(page.Url); using (SPLimitedWebPartManager webPartManager = page.GetLimitedWebPartManager (PersonalizationScope.Shared)) { } } } }
With this code segment I’m just connecting to a site and iterating over the page collection, grabbing and instance of the page’s SPLimitedWebPartManager as I go. Since SPLimitedWebPartManager implements the IDisposable pattern I am being a good citizen and wrapping its instantiation in a using {} block. The problem with this code segment is that this is what it does to the process memory:
Now, if I change the source code to this:
while(true) { using (SPSite siteCollection = new SPSite("http://localhost")) using (SPWeb site = siteCollection.OpenWeb("/Marketing")) { SPFolder pagesFolder = site.GetFolder("Pages"); foreach (SPFile page in pagesFolder.Files) { WL(page.Url); using (SPLimitedWebPartManager webPartManager = page.GetLimitedWebPartManager (PersonalizationScope.Shared)) { webPartManager.Web.Dispose(); } } } }
The memory picture looks much different now:
The only difference being the addition of an explicit Dispose() within the webPartManager using.
A look inside the SPFile.GetLimitedWebPartManager call reveals that it calls an internal GetLimitedWebPartManagerInternal() method on the SPFile SPWeb member variable. A closer look at this method shows the following code:
SPWeb web = this.Site.OpenWeb(); if (this.AllowUnsafeUpdates) { web.AllowUnsafeUpdates = this.AllowUnsafeUpdates; } SPWebPartManager manager = web.GetWebPartManagerInternal(pageUrl, requestedView, forRender, includeHidden, out bytes);
We see here that a new SPWeb object is getting spun up, and in the call to GetWebPartManagerInternal an assignment is going to be made to the SPLimitedWebPartManager m_web member variable. If we look at the Dispose() implementation for SPLimitedWebPartManager, we see the following:
public void Dispose() { if (!this.m_disposed) { if (this.m_manager != null) { this.m_manager.Dispose(); } } else { return; } this.m_webParts = null; this.m_manager = null; this.m_disposed = true; }
Nothing is being done to dispose of the m_web! If I explicitly dispose of m_web, then memory stays low.
Is anyone encountering the same?


Jason Fant
08. Jun, 2007
Interestingly enough, Tom Sallese and I attended a session at TechEd today covering the WSS object model. One of the things that the speaker covered as a little known “gotcha” was exactly what you are talking about. It appears that we are going to have to be really careful when playing with the SharePoint’s object model. Good looking out B.
Peter {faa780ce-0f0a-4c28-81d2-3667b71287fd}
28. Sep, 2007
Yes, this is exactly what I saw. It didn’t surprise me at all when I got my “outofmemoryexception”; I already had a healthy fear of SharePoint.
Shai
24. Oct, 2007
Hi,
I fail to understand why you feel that disposing of the web part manager should also dispose its owner web?
for instance, if you have code like this:
spweb w = …..
SPLimitedWebPartManager mgr = w.OpenFile(“…”).GetLimitedWebPartManager(…);
mgr.AddWebPart(…);
mgr.Dispose();
w.Title += ” Done!”;
w.Update();
w.Dispose();
See, I continue to work on the web object after disposing of the limited web part manager… It would be a bug if my w.TItle update will fail… no?
admin
24. Oct, 2007
The difference is that the web part manager is not using your w instance, it creates its own instance on the following line:
SPWeb web = this.Site.OpenWeb();
In your example you actually have 2 instances of SPWeb, you have your instance “w”, and then there is an instance encapsulated in the web part manager “web”. The web part manager should dispose of the “web” instance, not your “w” instance.
Incanna
08. May, 2009
ehh. interesting..
JessicaRich
10. May, 2009
Thanks for posting, definitely going to subscribe! See you on my reader.
ArianaSype
13. May, 2009
Wow! Thank you very much! I always wanted to write in my site something like that
Tudor Iliescu
01. Nov, 2011
Very interesting! It the same in 2010?
bryan
01. Nov, 2011
From what I’ve seen, yes. I poked around in SPLimitedWebPartManager for 2010 and it still does not appear to close the SPWeb object that it opens up, so I would recommend still explicitly closing it. If anyone has seen differently in 2010 let me know!
Adrian Iurov
18. Nov, 2011
From what I’ve seen in the code, this is NOT a memory leak in SP2010.
These 2 fields are part of the SPLimitedWebPartManager class:
SPWeb m_web;
SPWebPartManager m_manager;
When Dispose() is called on SPLimitedWebPartManager, inside it calls m_manager.Dispose() which calls m_web.Dipose()
The m_web of the SPWebPartManager instance references the same SPWeb instance as the m_web of the SPLimitedWebPartManager instance.
In order to see that the 2 fields reference the same SPWeb instance, take a look at the way this m_web is opened inside SPWeb.GetLimitedWebPartManagerInternal. Later on is assigned to the m_web of a SPWebPartCollectionInitialState instance and in the end to the newly created SPWebPartManager instance.
It’s a bit hard to follow, but if you need more details about the entire flow, I could provide them to you.
bryan
18. Nov, 2011
Ah, you’re right Adrian! When I looked earlier I just took a quick glance at Dispose() and noticed it still wasn’t cleaning it up, but you’re right, it’s no longer creating the instance inside of SPLimitedWebPartManager, instead it’s point to an instance created by SPWebPartManager, and SPWebPartManager cleans up the SPWeb object.
Thanks for the correction!