Closed
Bug 179498
Opened 22 years ago
Closed 22 years ago
memory leak on reloading an image
Categories
(Core :: DOM: Core & HTML, defect)
Tracking
()
RESOLVED
FIXED
People
(Reporter: ajschult784, Assigned: keeda)
References
()
Details
(Keywords: memory-leak)
Attachments
(3 files)
992 bytes,
patch
|
Details | Diff | Splinter Review | |
14.40 KB,
text/plain
|
Details | |
1.45 KB,
patch
|
jst
:
review+
bzbarsky
:
superreview+
|
Details | Diff | Splinter Review |
originally reported in bug 174760 with linux CVS trunk build 20021108
Reloaded car2.jpg from the URL (locally) about 12 times.
Valgrind came up with this:
676 bytes in 13 blocks are possibly lost
malloc (vg_clientfuncs.c:100)
__builtin_new (nsAppRunner.cpp:178)
operator new(unsigned) (vg_clientfuncs.c:139)
NS_NewHTMLImageElement() (nsHTMLImageElement.cpp:181)
nsImageDocument::CreateSyntheticDocument() (nsImageDocument.cpp:329)
nsImageDocument::StartDocumentLoad() (nsImageDocument.cpp:265)
nsContentDLF::CreateDocument() (nsContentDLF.cpp:435)
nsContentDLF::CreateInstance() (nsContentDLF.cpp:233)
and
1040 bytes in 13 blocks are possibly lost
malloc (vg_clientfuncs.c:100)
__builtin_new (nsAppRunner.cpp:178)
operator new(unsigned) (vg_clientfuncs.c:139)
nsScriptSecurityManager::GetCodebasePrincipal() (nsScriptSecurityManager.cpp:1744)
nsDocument::GetPrincipal() (nsDocument.cpp:915)
GlobalWindowImpl::GetPrincipal() (nsGlobalWindow.cpp:895)
nsScriptSecurityManager::GetPrincipalAndFrame() (nsScriptSecurityManager.cpp:1876)
nsScriptSecurityManager::GetSubjectPrincipal() (nsScriptSecurityManager.cpp:1895)
the first chunk looks more relevant, but both have lucky number 13.
hopefully this component is appropriate.
Comment 1•22 years ago
|
||
> NS_NewHTMLImageElement() (nsHTMLImageElement.cpp:181)
This looks bogus; we release the pointer at the end of the function (though
switching this code to nsCOMPtr may be a good idea in any case).
> nsScriptSecurityManager::GetCodebasePrincipal() (nsScriptSecurityManager.cpp:1744)
That looks bogus-ish as well; we release it properly in the nsDocument
destructor....
Keywords: mlk
Reporter | ||
Comment 2•22 years ago
|
||
the nsHTMLImageElement is ADDREF'd once at nsHTMLImageElement:955 and then again
with this stack:
#3 nsGenericHTMLContainerElement::AppendChildTo(nsIContent*, int, int) (
this=0x8770f08, aKid=0x86aa7c8, aNotify=0, aDeepSetDocument=0) at
nsGenericHTMLElement.cpp:4069
#4 nsImageDocument::CreateSyntheticDocument() (this=0x87a4158)
at nsImageDocument.cpp:359
It is RELEASE'd only once (nsImageDocument.cpp:362), hence the memory leak.
Assignee | ||
Comment 3•22 years ago
|
||
This bug is bad. Pretty big leak.
Valgrind is telling the truth. But its telling only a very small part of the
truth. The image element and the priciple that it showed are small fish. I'll
attach logs that show we are leaking a whole lot of stuff from all over the
place for every nsImageDocument that we construct. As such, to hit this there is
no need to reload the same image, even the first load leaks.
It looks like there is a cycle involving nsImageDocument and the imgRequest,
probably through ImageListener. I dont know enough about imglib to be able to
specify exacty all the links in the cycle; but we end up leaking a ton stuff
from imglib and layout, along with all the stuff that the document owns.
Explicitly dropping the documents ref to the img nsImageDocument::EndLayout()
appears to successfully break the cycle without causing any other problems.
Patch/leaklogs in a moment.
Assignee | ||
Comment 4•22 years ago
|
||
Assignee | ||
Comment 5•22 years ago
|
||
Logs collected by doing simply:
* Start up mozilla
* Load http://foo/bar.jpg
* Shutdown mozilla.
The first log is from before the patch, the second after.
Comment 6•22 years ago
|
||
Oh, good catch....
One thought (and this would test your ImageListener hypothesis, which seems to
me to be the mosst likely one). The document may want to have the imgIRequest
later so it can get image info out (eg for enhancements to page info). But once
the ImageListener has done its OnStopRequest, it does not need the mDocument
ref. So maybe we should null out mDocument in ImageListener::OnStopRequest?
Does that also fix the leak?
Comment 7•22 years ago
|
||
I just traced the ImageListener ownership, and it _looks_ like that's only owned
by the URILoader, which releases it in OnStopRequest...
Assignee | ||
Comment 8•22 years ago
|
||
Yep, the cycle is not through ImageListener.
Looks to me like it goes something like this:
ImageDocument > imgRequestProxy > GalleyContext(nsPresContext)
|> nsEventStateManager > ImageDocument
Does that sound correct? If it is correct, do we have a better way of breaking
that cycle than my patch above? Who would be the right person to review this?
Comment 9•22 years ago
|
||
Yeah, that's correct. :( The problem is basically that the document ends up
owning the prescontext through this mechanism... :(
The esm has this bizarre "[OWNER], but doesn't need to be." comment on
mDocument... is that an option here? Could the prescontext drop the ESM ref
when its container is set to null, maybe?
Of course we can also just use the patch we already have, but then any other
object owned by the document which holds a ref to an imgIRequest could cause
problems (eg there are thoughts to put those in the style system's storage
structs, which are owned by the doc in the end, etc.)
Also, if we ever make imgIRequest hold a ref to a document (instead of a
prescontext) the whole thing becomes even wose... :(
ccing some people who should be aware of this... I'd say that dbaron or bryner
are the best reviewers for this stuff.
One other option is to put the nulling out in
nsImageDocument::SetScriptGlobalObject or something along those lines (see
nsDocument).
Assignee | ||
Comment 10•22 years ago
|
||
I like bz's SetScriptGlobalObject idea better than the earlier patch (I don't
know enough about the esm yet to say if it needs the document ref or not.)
BTW, nsHTMLImageElement itself explicity drops its ref to its imgRequest in
OnStopDecode(), so this sort of thing seem to have precedent.
Comment 11•22 years ago
|
||
Comment on attachment 109010 [details] [diff] [review]
alternative patch (do the nulling out in SetScriptGlobalObject)
r/sr=me....
We still have a problem in that eventually we will want to have the style
system holding refs to imgIRequest objects... I guess we'll just have to make
sure we clear our all that stuff carefully. ;)
Attachment #109010 -
Flags: superreview+
Assignee | ||
Updated•22 years ago
|
Attachment #109010 -
Flags: review?(jst)
Comment 13•22 years ago
|
||
Comment on attachment 109010 [details] [diff] [review]
alternative patch (do the nulling out in SetScriptGlobalObject)
Nice catch! r/sr=jst
Attachment #109010 -
Flags: review?(jst) → review+
Comment 14•22 years ago
|
||
patch checked in.
Assignee | ||
Comment 15•22 years ago
|
||
Thanks bz!
Status: NEW → RESOLVED
Closed: 22 years ago
Resolution: --- → FIXED
Assignee | ||
Comment 16•22 years ago
|
||
*** Bug 171681 has been marked as a duplicate of this bug. ***
Comment 17•22 years ago
|
||
Confirming fixed on Mozilla/5.0 (Windows; U; WinNT4.0; en-US; rv:1.3a)
Gecko/20021214
After loading a huge set of different JPGs, either in tabs or windows, an
closing them again, memory consumption now goes back down to its original value.
Harshal, thanks a lot - you are my hero :-)
This bug was a royal pain in the nether regions!
Assignee | ||
Comment 18•22 years ago
|
||
*** Bug 184750 has been marked as a duplicate of this bug. ***
Comment 19•22 years ago
|
||
*** Bug 192126 has been marked as a duplicate of this bug. ***
Comment 20•22 years ago
|
||
*** Bug 112158 has been marked as a duplicate of this bug. ***
Comment 21•22 years ago
|
||
This bug seems to have regressed in the nightlies of 1.4. Memory load goes
drastically higher when many images loaded/unloaded, just like it was before
this bug was fixed.
I tested this with the 17/4 build, and also with a recent Phoenix build.
Updated•6 years ago
|
Component: DOM → DOM: Core & HTML
You need to log in
before you can comment on or make changes to this bug.
Description
•