Closed Bug 631536 Opened 13 years ago Closed 13 years ago

Constantly raising private bytes with setInterval("document.location.hash", 5);

Categories

(Core :: XPCOM, defect)

x86
Windows 7
defect
Not set
major

Tracking

()

RESOLVED DUPLICATE of bug 654399
Tracking Status
blocking2.0 --- .x+

People

(Reporter: mayhemer, Assigned: mayhemer)

References

()

Details

(Keywords: memory-leak, Whiteboard: [softblocker][MemShrink:P2])

Attachments

(1 file)

See URL.  On one machine I can see ~500-1000KB allocated (and not released) each seconds when this page is just open in a new tab.  On another I can see ~100KB allocated each second.  In few minutes this eats memory up on a machines w/ fewer RAM.

Seems reproducible just on Windows (confirmed 7 and XP).  

On OSX there is a constant slight CPU load seen when the page is open.
Can you either reduce the testcase (on Windows), or get some allocation stacks?  Does it happen if you turn off hardware acceleration?
(In reply to comment #1)
> Can you either reduce the testcase (on Windows)

Copying the whole page (Save as...) to my local server makes the case unreproducible.

> or get some allocation stacks?

How can I do that?  Put a breakpoint to some moz_alloc function?

>  Does it happen if you turn off hardware acceleration?

Turning off HW accel doesn't affect it.
Well, if this were not Windows I'd tell you to run massif....

Do we know a decent allocation profiler on windows?

Another option, if the VS debugger can do it, is to breakpoint in malloc and have it just log the stack and continue... then look at the resulting data.
Looks like a string leak with following callstack, allocating 1018 bytes with moz_malloc:

 	mozalloc.dll!moz_malloc(unsigned int size=1018)  Line 108	
 	xul.dll!nsStringBuffer::Alloc(unsigned int size=1010)  Line 209 + 0xd bytes	
 	xul.dll!nsAString_internal::MutatePrep(unsigned int capacity=504, wchar_t * * oldData=0x002dc764, unsigned int * oldFlags=0x002dc760)  Line 162 + 0x9 bytes	
 	xul.dll!nsAString_internal::ReplacePrepInternal(unsigned int cutStart=1, unsigned int cutLen=0, unsigned int fragLen=501, unsigned int newLen=502)  Line 198 + 0x13 bytes	
 	xul.dll!nsAString_internal::ReplacePrep(unsigned int cutStart=1, unsigned int cutLength=0, unsigned int newLength=501)  Line 685	
 	xul.dll!nsAString_internal::Replace(unsigned int cutStart=1, unsigned int cutLength=0, const wchar_t * data=0x11160768, unsigned int length=501)  Line 487 + 0x1a bytes	
 	xul.dll!nsAString_internal::Replace(unsigned int cutStart=1, unsigned int cutLength=0, const nsAString_internal & str={...})  Line 378 + 0x28 bytes	
 	xul.dll!nsAString_internal::Append(const nsAString_internal & str={...})  Line 385 + 0x1c bytes	
 	xul.dll!nsLocation::GetHash(nsAString_internal & aHash={...})  Line 408	
 	xul.dll!NS_InvokeByIndex_P(nsISupports * that=0x10f68ef8, unsigned int methodIndex=3, unsigned int paramCount=1, nsXPTCVariant * params=0x002dca98)  Line 103	
 	xul.dll!CallMethodHelper::Invoke()  Line 3099 + 0x1c bytes	
 	xul.dll!CallMethodHelper::Call()  Line 2363 + 0x8 bytes	
 	xul.dll!XPCWrappedNative::CallMethod(XPCCallContext & ccx={...}, XPCWrappedNative::CallMode mode=CALL_GETTER)  Line 2327 + 0x16 bytes	
 	xul.dll!XPCWrappedNative::GetAttribute(XPCCallContext & ccx={...})  Line 2651 + 0xe bytes	
>	xul.dll!XPC_WN_GetterSetter(JSContext * cx=0x1041ebd8, unsigned int argc=0, jsval_layout * vp=0x067400e8)  Line 1643 + 0xc bytes	
 	mozjs.dll!js::CallJSNative(JSContext * cx=0x1041ebd8, int (JSContext *, unsigned int, js::Value *)* native=0x64d10fd0, unsigned int argc=0, js::Value * vp=0x067400e8)  Line 697 + 0xf bytes	
 	mozjs.dll!js::Invoke(JSContext * cx=0x1041ebd8, const js::CallArgs & argsRef={...}, unsigned int flags=0)  Line 683 + 0x22 bytes	
 	mozjs.dll!js::ExternalInvoke(JSContext * cx=0x1041ebd8, const js::Value & thisv={...}, const js::Value & fval={...}, unsigned int argc=0, js::Value * argv=0x00000000, js::Value * rval=0x002dcf44)  Line 841 + 0xf bytes	
 	mozjs.dll!js::ExternalGetOrSet(JSContext * cx=0x1041ebd8, JSObject * obj=0x0db27f30, jsid id={...}, const js::Value & fval={...}, JSAccessMode mode=JSACC_READ, unsigned int argc=0, js::Value * argv=0x00000000, js::Value * rval=0x002dcf44)  Line 881 + 0x2a bytes	
 	mozjs.dll!js::JSProxyHandler::get(JSContext * cx=0x1041ebd8, JSObject * proxy=0x0db27f30, JSObject * receiver=0x0db27f30, jsid id={...}, js::Value * vp=0x002dcf44)  Line 131 + 0x2c bytes	
 	xul.dll!xpc::XrayWrapper<JSWrapper>::get(JSContext * cx=0x1041ebd8, JSObject * wrapper=0x0db27f30, JSObject * receiver=0x0db27f30, jsid id={...}, js::Value * vp=0x002dcf44)  Line 766	
 	mozjs.dll!js::JSProxy::get(JSContext * cx=0x1041ebd8, JSObject * proxy=0x0db27f30, JSObject * receiver=0x0db27f30, jsid id={...}, js::Value * vp=0x002dcf44)  Line 798 + 0x2c bytes	
 	mozjs.dll!js::proxy_GetProperty(JSContext * cx=0x1041ebd8, JSObject * obj=0x0db27f30, JSObject * receiver=0x0db27f30, jsid id={...}, js::Value * vp=0x002dcf44)  Line 915 + 0x19 bytes	
 	mozjs.dll!JSObject::getProperty(JSContext * cx=0x1041ebd8, JSObject * receiver=0x0db27f30, jsid id={...}, js::Value * vp=0x002dcf44)  Line 1198 + 0x2c bytes	
 	mozjs.dll!JSObject::getProperty(JSContext * cx=0x1041ebd8, jsid id={...}, js::Value * vp=0x002dcf44)  Line 1203	
 	mozjs.dll!InlineGetProp(js::VMFrame & f={...})  Line 1910 + 0x63 bytes	
 	mozjs.dll!js::mjit::stubs::GetProp(js::VMFrame & f={...})  Line 1922 + 0x8 bytes	
 	mozjs.dll!DisabledGetPropIC(js::VMFrame & f={...}, js::mjit::ic::PICInfo * pic=0x110d9c68)  Line 1625	
 	1047b291()	
 	mozjs.dll!js::mjit::EnterMethodJIT(JSContext * cx=0x1041ebd8, JSStackFrame * fp=0x06740030, void * code=0x059cbad0, js::Value * stackLimit=0x067cca60)  Line 748 + 0x15 bytes	
 	mozjs.dll!CheckStackAndEnterMethodJIT(JSContext * cx=0x1041ebd8, JSStackFrame * fp=0x06740030, void * code=0x059cbad0)  Line 774 + 0x15 bytes	
 	mozjs.dll!js::mjit::JaegerShot(JSContext * cx=0x1041ebd8)  Line 791 + 0x19 bytes	
 	mozjs.dll!js::RunScript(JSContext * cx=0x1041ebd8, JSScript * script=0x0fc37378, JSStackFrame * fp=0x06740030)  Line 637 + 0x9 bytes	
 	mozjs.dll!js::Execute(JSContext * cx=0x1041ebd8, JSObject * chain=0x0d6e5668, JSScript * script=0x0fc37378, JSStackFrame * prev=0x00000000, unsigned int flags=0, js::Value * result=0x00000000)  Line 1006 + 0x16 bytes	
 	mozjs.dll!EvaluateUCScriptForPrincipalsCommon(JSContext * cx=0x1041ebd8, JSObject * obj=0x0d6e5668, JSPrincipals * principals=0x10231604, const wchar_t * chars=0x0c2fff60, unsigned int length=28, const char * filename=0x10376110, unsigned int lineno=1, jsval_layout * rval=0x00000000, JSVersion compileVersion=JSVERSION_DEFAULT)  Line 4934 + 0x22 bytes	
 	mozjs.dll!JS_EvaluateUCScriptForPrincipalsVersion(JSContext * cx=0x1041ebd8, JSObject * obj=0x0d6e5668, JSPrincipals * principals=0x10231604, const wchar_t * chars=0x0c2fff60, unsigned int length=28, const char * filename=0x10376110, unsigned int lineno=1, jsval_layout * rval=0x00000000, JSVersion version=JSVERSION_DEFAULT)  Line 4950 + 0x2e bytes	
 	xul.dll!nsJSContext::EvaluateString(const nsAString_internal & aScript={...}, void * aScopeObject=0x0d6e5668, nsIPrincipal * aPrincipal=0x10231600, const char * aURL=0x10376110, unsigned int aLineNo=1, unsigned int aVersion=0, nsAString_internal * aRetValue=0x00000000, int * aIsUndefined=0x002dd33c)  Line 1554 + 0x4c bytes	
 	xul.dll!nsGlobalWindow::RunTimeout(nsTimeout * aTimeout=0x10376198)  Line 9090 + 0xb6 bytes	
 	xul.dll!nsGlobalWindow::TimerCallback(nsITimer * aTimer=0x10376220, void * aClosure=0x10376198)  Line 9453	
 	xul.dll!nsTimerImpl::Fire()  Line 425 + 0xe bytes	
 	xul.dll!nsTimerEvent::Run()  Line 519	
 	xul.dll!nsThread::ProcessNextEvent(int mayWait=1, int * result=0x002dd560)  Line 633 + 0x19 bytes	
 	xul.dll!NS_ProcessNextEvent_P(nsIThread * thread=0x00d44680, int mayWait=1)  Line 250 + 0x16 bytes	
 	xul.dll!mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate * aDelegate=0x00d40e28)  Line 134 + 0xe bytes	
 	xul.dll!MessageLoop::RunInternal()  Line 220	
 	xul.dll!MessageLoop::RunHandler()  Line 203	
 	xul.dll!MessageLoop::Run()  Line 177	
 	xul.dll!nsBaseAppShell::Run()  Line 198	
 	xul.dll!nsAppShell::Run()  Line 258 + 0x9 bytes	
 	xul.dll!nsAppStartup::Run()  Line 220 + 0x1c bytes	
 	xul.dll!XRE_main(int argc=3, char * * argv=0x00d3c4a8, const nsXREAppData * aAppData=0x00d3cbc8)  Line 3762 + 0x25 bytes	
 	firefox.exe!NS_internal_main(int argc=3, char * * argv=0x00d3c4a8)  Line 158 + 0x12 bytes	
 	firefox.exe!wmain(int argc=3, wchar_t * * argv=0x00d30cf0)  Line 128 + 0xd bytes	
 	firefox.exe!__tmainCRTStartup()  Line 583 + 0x19 bytes	
 	firefox.exe!wmainCRTStartup()  Line 403	


JS stack (not really useful):

0 anonymous() ["http://w.sharethis.com/share4x/js/st.6b38bb153d12c6097f381edebf08d372.js":1]
    tempFucn = undefined
    tempFun = undefined
    evStr = undefined
    i = undefined
    temp = undefined
    cmd = undefined
    args = undefined
    hash = undefined
    this = [object Object]
1 <TOP LEVEL> ["http://w.sharethis.com/share4x/js/st.6b38bb153d12c6097f381edebf08d372.js":1]
    this = [object Window @ 0x102e5ff8 (native @ 0x1030dd88)]
Keywords: mlk
Are we leaking (or failing to finalize) the JSString objects involved or something?
The buffer is not released by ::ReleaseData because mFlags gets modified by misplaced allocation.  Stack trace:

>	ntdll.dll!_RtlpValidateHeap@8()  + 0x9 bytes	
 	ntdll.dll!_RtlDebugAllocateHeap@12()  + 0xab bytes	
 	ntdll.dll!@RtlpAllocateHeap@24()  + 0x57d27 bytes	
 	ntdll.dll!_RtlAllocateHeap@12()  + 0x502a bytes	
 	msvcr90d.dll!_heap_alloc_base(unsigned int size=86)  Line 105 + 0x28 bytes	
 	msvcr90d.dll!_heap_alloc_dbg_impl(unsigned int nSize=50, int nBlockUse=1, const char * szFileName=0x00000000, int nLine=0, int * errno_tmp=0x0018cacc)  Line 427 + 0x9 bytes	
 	msvcr90d.dll!_nh_malloc_dbg_impl(unsigned int nSize=50, int nhFlag=0, int nBlockUse=1, const char * szFileName=0x00000000, int nLine=0, int * errno_tmp=0x0018cacc)  Line 239 + 0x19 bytes	
 	msvcr90d.dll!_nh_malloc_dbg(unsigned int nSize=50, int nhFlag=0, int nBlockUse=1, const char * szFileName=0x00000000, int nLine=0)  Line 296 + 0x1d bytes	
 	msvcr90d.dll!malloc(unsigned int nSize=50)  Line 56 + 0x15 bytes	
 	mozalloc.dll!moz_malloc(unsigned int size=50)  Line 108 + 0xa bytes	
 	xul.dll!nsStringBuffer::Alloc(unsigned int size=42)  Line 209 + 0xd bytes	
 	xul.dll!nsAString_internal::MutatePrep(unsigned int capacity=20, wchar_t * * oldData=0x0018cb70, unsigned int * oldFlags=0x0018cb6c)  Line 162 + 0x9 bytes	
 	xul.dll!nsAString_internal::Assign(const nsSubstringTuple & tuple={...})  Line 415 + 0x13 bytes	
 	xul.dll!nsAString_internal::nsAString_internal(const nsSubstringTuple & tuple={...})  Line 576	
 	xul.dll!nsXBLPrototypeHandler::ExecuteHandler(nsPIDOMEventTarget * aTarget=0x080fcd30, nsIDOMEvent * aEvent=0x0c637650)  Line 263 + 0x43 bytes	
 	xul.dll!nsXBLEventHandler::HandleEvent(nsIDOMEvent * aEvent=0x0c637650)  Line 90	
 	xul.dll!nsEventListenerManager::HandleEventSubType(nsListenerStruct * aListenerStruct=0x08994dd8, nsIDOMEventListener * aListener=0x086a28e0, nsIDOMEvent * aDOMEvent=0x0c637650, nsPIDOMEventTarget * aCurrentTarget=0x080fcd30, unsigned int aPhaseFlags=2, nsCxPusher * aPusher=0x0018d008)  Line 1127 + 0x12 bytes	
 	xul.dll!nsEventListenerManager::HandleEventInternal(nsPresContext * aPresContext=0x00000000, nsEvent * aEvent=0x0e016d70, nsIDOMEvent * * aDOMEvent=0x0018cff8, nsPIDOMEventTarget * aCurrentTarget=0x080fcd30, unsigned int aFlags=2, nsEventStatus * aEventStatus=0x0018cffc, nsCxPusher * aPusher=0x0018d008)  Line 1224 + 0x27 bytes	
 	xul.dll!nsEventListenerManager::HandleEvent(nsPresContext * aPresContext=0x00000000, nsEvent * aEvent=0x0e016d70, nsIDOMEvent * * aDOMEvent=0x0018cff8, nsPIDOMEventTarget * aCurrentTarget=0x080fcd30, unsigned int aFlags=2, nsEventStatus * aEventStatus=0x0018cffc, nsCxPusher * aPusher=0x0018d008)  Line 147	
 	xul.dll!nsEventTargetChainItem::HandleEvent(nsEventChainPostVisitor & aVisitor={...}, unsigned int aFlags=2, int aMayHaveNewListenerManagers=0, nsCxPusher * aPusher=0x0018d008)  Line 213	
 	xul.dll!nsEventTargetChainItem::HandleEventTargetChain(nsEventChainPostVisitor & aVisitor={...}, unsigned int aFlags=6, nsDispatchingCallback * aCallback=0x00000000, int aMayHaveNewListenerManagers=0, nsCxPusher * aPusher=0x0018d008)  Line 366	
 	xul.dll!nsEventDispatcher::Dispatch(nsISupports * aTarget=0x092f7190, nsPresContext * aPresContext=0x00000000, nsEvent * aEvent=0x0e016d70, nsIDOMEvent * aDOMEvent=0x0c637650, nsEventStatus * aEventStatus=0x0018d158, nsDispatchingCallback * aCallback=0x00000000, nsCOMArray<nsPIDOMEventTarget> * aTargets=0x00000000)  Line 628 + 0x1e bytes	
 	xul.dll!nsEventDispatcher::DispatchDOMEvent(nsISupports * aTarget=0x092f7190, nsEvent * aEvent=0x00000000, nsIDOMEvent * aDOMEvent=0x0c637650, nsPresContext * aPresContext=0x00000000, nsEventStatus * aEventStatus=0x0018d158)  Line 691 + 0x1d bytes	
 	xul.dll!nsDOMEventTargetHelper::DispatchDOMEvent(nsEvent * aEvent=0x00000000, nsIDOMEvent * aDOMEvent=0x0c637650, nsPresContext * aPresContext=0x00000000, nsEventStatus * aEventStatus=0x0018d158)  Line 229 + 0x19 bytes	
 	xul.dll!nsContentUtils::DispatchChromeEvent(nsIDocument * aDoc=0x0c5da0f0, nsISupports * aTarget=0x0c5da0f0, const nsAString_internal & aEventName={...}, int aCanBubble=1, int aCancelable=1, int * aDefaultAction=0x00000000)  Line 3438 + 0x1e bytes	
 	xul.dll!nsDocument::DoNotifyPossibleTitleChange()  Line 5293 + 0x2c bytes	
 	xul.dll!nsRunnableMethodImpl<void (__thiscall nsDocument::*)(void),0>::Run()  Line 346	
 	xul.dll!nsThread::ProcessNextEvent(int mayWait=0, int * result=0x0018d2e8)  Line 633 + 0x19 bytes	
 	xul.dll!NS_ProcessNextEvent_P(nsIThread * thread=0x008d4610, int mayWait=0)  Line 250 + 0x16 bytes	
 	xul.dll!mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate * aDelegate=0x008d1088)  Line 110 + 0xe bytes	
 	xul.dll!MessageLoop::RunInternal()  Line 220	
 	xul.dll!MessageLoop::RunHandler()  Line 203	
 	xul.dll!MessageLoop::Run()  Line 177	
 	xul.dll!nsBaseAppShell::Run()  Line 198	
 	xul.dll!nsAppShell::Run()  Line 258 + 0x9 bytes	
 	xul.dll!nsAppStartup::Run()  Line 220 + 0x1c bytes	
 	xul.dll!XRE_main(int argc=3, char * * argv=0x008cc4a8, const nsXREAppData * aAppData=0x008ccbc8)  Line 3762 + 0x25 bytes	
 	firefox.exe!NS_internal_main(int argc=3, char * * argv=0x008cc4a8)  Line 158 + 0x12 bytes	
 	firefox.exe!wmain(int argc=3, wchar_t * * argv=0x008c0cf0)  Line 128 + 0xd bytes	
 	firefox.exe!__tmainCRTStartup()  Line 583 + 0x19 bytes	
 	firefox.exe!wmainCRTStartup()  Line 403	


The string instance that calls nsAString_internal::MutatePrep here IS NOT the same instance as the one the flags are being overwritten.
This needs to block.
blocking2.0: --- → ?
Component: General → XPCOM
Product: Firefox → Core
QA Contact: general → xpcom
And one more note: the leaking nsAString instance is just a single one.  We do not release correctly on reallocation, this is a cycle of calls on places that allocs/deallocs:

nsAString_internal::MutatePrep() - calls nsStringBuffer::Alloc
nsAString_internal::ReplacePrepInternal() - calls ::ReleaseData <= NOT RELEASING
nsAString_internal::Finalize(void) - calls ::ReleaseData
nsAString_internal::SetCapacity() - calls ::ReleaseData
nsAString_internal::ReplacePrepInternal() - calls ::ReleaseData
nsAString_internal::MutatePrep() - calls nsStringBuffer::Alloc
nsAString_internal::ReplacePrepInternal - calls ::ReleaseData <= NOT RELEASING
etc...
Blocking, and Cc:ing some more people who may have ideas on this string data leak. And assigning to Honza for now, as he's clearly able to reproduce. Honza, please speak up if you need help here.
Assignee: nobody → honzab.moz
blocking2.0: ? → final+
Whiteboard: [softblocker]
Comment 7 and comment 9 might be wrong.  According to comment 9, and fact that nsAString_internal::Finalize is called just in the destructor, the instance has been released and then allocated at the same position (happens often on windows).

So, we probably just wrongly play with the flags somewhere.
We call AddRef() on some buffers more then ones.

// New storage created, ref cnt == 1 initially, will be released in the string destructor
NEW: this=0x13c6f2d0 {mRefCount=1 mStorageSize=1010 }, mRefCount=1, 	xul.dll!nsStringBuffer::Alloc() 
	xul.dll!nsAString_internal::MutatePrep() 
	xul.dll!nsAString_internal::ReplacePrepInternal() 
	xul.dll!nsAString_internal::ReplacePrep() 
	xul.dll!nsAString_internal::Replace() 
	xul.dll!nsAString_internal::Replace() 
	xul.dll!nsAString_internal::Append() 
	xul.dll!nsLocation::GetHash() 
	xul.dll!NS_InvokeByIndex_P() 
	xul.dll!CallMethodHelper::Invoke() 
	xul.dll!CallMethodHelper::Call() 
	xul.dll!XPCWrappedNative::CallMethod() 
	xul.dll!XPCWrappedNative::GetAttribute() 
	xul.dll!XPC_WN_GetterSetter() 
	mozjs.dll!js::CallJSNative() 
	mozjs.dll!js::Invoke() 
	mozjs.dll!js::ExternalInvoke() 
	mozjs.dll!js::ExternalGetOrSet() 
	mozjs.dll!js::JSProxyHandler::get() 
	xul.dll!xpc::XrayWrapper<JSWrapper>::get() 
	mozjs.dll!js::JSProxy::get() 
	mozjs.dll!js::proxy_GetProperty() 
	mozjs.dll!JSObject::getProperty() 
	mozjs.dll!JSObject::getProperty() 
	mozjs.dll!InlineGetProp() 
	mozjs.dll!js::mjit::stubs::GetProp() 
	mozjs.dll!DisabledGetPropIC() 
	12c74be1()
	mozjs.dll!js::mjit::EnterMethodJIT() 
	mozjs.dll!CheckStackAndEnterMethodJIT() 
	mozjs.dll!js::mjit::JaegerShot() 
	mozjs.dll!js::RunScript() 
	mozjs.dll!js::Execute() 
	mozjs.dll!EvaluateUCScriptForPrincipalsCommon() 
	mozjs.dll!JS_EvaluateUCScriptForPrincipalsVersion() 
	xul.dll!nsJSContext::EvaluateString() 
	xul.dll!nsGlobalWindow::RunTimeout() 
	xul.dll!nsGlobalWindow::TimerCallback() 
	xul.dll!nsTimerImpl::Fire() 
	xul.dll!nsTimerEvent::Run() 
	xul.dll!nsThread::ProcessNextEvent() 
	xul.dll!NS_ProcessNextEvent_P() 
	xul.dll!mozilla::ipc::MessagePump::Run() 
	xul.dll!MessageLoop::RunInternal() 
	xul.dll!MessageLoop::RunHandler() 
	xul.dll!MessageLoop::Run() 
	xul.dll!nsBaseAppShell::Run() 
	xul.dll!nsAppShell::Run() 
	xul.dll!nsAppStartup::Run() 
	xul.dll!XRE_main() 
	firefox.exe!NS_internal_main() 
	firefox.exe!wmain() 
	firefox.exe!__tmainCRTStartup() 
	firefox.exe!wmainCRTStartup() 
	kernel32.dll!75ac3677() 
	[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]
	ntdll.dll!76f79d42() 
	ntdll.dll!76f79d15() 

// JS adds a ref here, mRefCount is the number on entering the AddRef method, so it is 2 when it is left	
ADD: this=0x13c6f2d0 {mRefCount=1 mStorageSize=1010 }, mRefCount=1, 	xul.dll!nsStringBuffer::AddRef() 
	xul.dll!XPCConvert::NativeData2JS() 
	xul.dll!XPCConvert::NativeData2JS() 
	xul.dll!CallMethodHelper::GatherAndConvertResults() 
	xul.dll!CallMethodHelper::Call() 
	xul.dll!XPCWrappedNative::CallMethod() 
	xul.dll!XPCWrappedNative::GetAttribute() 
	xul.dll!XPC_WN_GetterSetter() 
	mozjs.dll!js::CallJSNative() 
	mozjs.dll!js::Invoke() 
	mozjs.dll!js::ExternalInvoke() 
	mozjs.dll!js::ExternalGetOrSet() 
	mozjs.dll!js::JSProxyHandler::get() 
	xul.dll!xpc::XrayWrapper<JSWrapper>::get() 
	mozjs.dll!js::JSProxy::get() 
	mozjs.dll!js::proxy_GetProperty() 
	mozjs.dll!JSObject::getProperty() 
	mozjs.dll!JSObject::getProperty() 
	mozjs.dll!InlineGetProp() 
	mozjs.dll!js::mjit::stubs::GetProp() 
	mozjs.dll!DisabledGetPropIC() 
	12c74be1()
	mozjs.dll!js::mjit::EnterMethodJIT() 
	mozjs.dll!CheckStackAndEnterMethodJIT() 
	mozjs.dll!js::mjit::JaegerShot() 
	mozjs.dll!js::RunScript() 
	mozjs.dll!js::Execute() 
	mozjs.dll!EvaluateUCScriptForPrincipalsCommon() 
	mozjs.dll!JS_EvaluateUCScriptForPrincipalsVersion() 
	xul.dll!nsJSContext::EvaluateString() 
	xul.dll!nsGlobalWindow::RunTimeout() 
	xul.dll!nsGlobalWindow::TimerCallback() 
	xul.dll!nsTimerImpl::Fire() 
	xul.dll!nsTimerEvent::Run() 
	xul.dll!nsThread::ProcessNextEvent() 
	xul.dll!NS_ProcessNextEvent_P() 
	xul.dll!mozilla::ipc::MessagePump::Run() 
	xul.dll!MessageLoop::RunInternal() 
	xul.dll!MessageLoop::RunHandler() 
	xul.dll!MessageLoop::Run() 
	xul.dll!nsBaseAppShell::Run() 
	xul.dll!nsAppShell::Run() 
	xul.dll!nsAppStartup::Run() 
	xul.dll!XRE_main() 
	firefox.exe!NS_internal_main() 
	firefox.exe!wmain() 
	firefox.exe!__tmainCRTStartup() 
	firefox.exe!wmainCRTStartup() 
	kernel32.dll!75ac3677() 
	[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]
	ntdll.dll!76f79d42() 
	ntdll.dll!76f79d15() 
	
// Destructor of the string releases its ref
REL: this=0x13c6f2d0 {mRefCount=2 mStorageSize=1010 }, mRefCount=2, 	xul.dll!nsStringBuffer::Release() 
	xul.dll!ReleaseData() 
	xul.dll!nsAString_internal::Finalize() 
	xul.dll!nsAString_internal::~nsAString_internal() 
	xul.dll!nsString::~nsString() 
	xul.dll!nsFixedString::~nsFixedString() 
	xul.dll!nsAutoString::~nsAutoString() 
	xul.dll!nsAutoString::`scalar deleting destructor'() 
	xul.dll!js::LazilyConstructed<nsAutoString>::~LazilyConstructed<nsAutoString>() 
	xul.dll!CallMethodHelper::~CallMethodHelper() 
	xul.dll!XPCWrappedNative::CallMethod() 
	xul.dll!XPCWrappedNative::GetAttribute() 
	xul.dll!XPC_WN_GetterSetter() 
	mozjs.dll!js::CallJSNative() 
	mozjs.dll!js::Invoke() 
	mozjs.dll!js::ExternalInvoke() 
	mozjs.dll!js::ExternalGetOrSet() 
	mozjs.dll!js::JSProxyHandler::get() 
	xul.dll!xpc::XrayWrapper<JSWrapper>::get() 
	mozjs.dll!js::JSProxy::get() 
	mozjs.dll!js::proxy_GetProperty() 
	mozjs.dll!JSObject::getProperty() 
	mozjs.dll!JSObject::getProperty() 
	mozjs.dll!InlineGetProp() 
	mozjs.dll!js::mjit::stubs::GetProp() 
	mozjs.dll!DisabledGetPropIC() 
	12c74be1()
	mozjs.dll!js::mjit::EnterMethodJIT() 
	mozjs.dll!CheckStackAndEnterMethodJIT() 
	mozjs.dll!js::mjit::JaegerShot() 
	mozjs.dll!js::RunScript() 
	mozjs.dll!js::Execute() 
	mozjs.dll!EvaluateUCScriptForPrincipalsCommon() 
	mozjs.dll!JS_EvaluateUCScriptForPrincipalsVersion() 
	xul.dll!nsJSContext::EvaluateString() 
	xul.dll!nsGlobalWindow::RunTimeout() 
	xul.dll!nsGlobalWindow::TimerCallback() 
	xul.dll!nsTimerImpl::Fire() 
	xul.dll!nsTimerEvent::Run() 
	xul.dll!nsThread::ProcessNextEvent() 
	xul.dll!NS_ProcessNextEvent_P() 
	xul.dll!mozilla::ipc::MessagePump::Run() 
	xul.dll!MessageLoop::RunInternal() 
	xul.dll!MessageLoop::RunHandler() 
	xul.dll!MessageLoop::Run() 
	xul.dll!nsBaseAppShell::Run() 
	xul.dll!nsAppShell::Run() 
	xul.dll!nsAppStartup::Run() 
	xul.dll!XRE_main() 
	firefox.exe!NS_internal_main() 
	firefox.exe!wmain() 
	firefox.exe!__tmainCRTStartup() 
	firefox.exe!wmainCRTStartup() 
	kernel32.dll!75ac3677() 
	[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]
	ntdll.dll!76f79d42() 
	ntdll.dll!76f79d15() 
	

And the second addref by JS [1] is not released.

[1] http://mxr.mozilla.org/mozilla-central/source/js/src/xpconnect/src/xpcconvert.cpp#356
Yeah, and since now I have no idea how to continue.  Someone take this please or let me know how to proceed.
This *could* be related to bug 614347.
> And the second addref by JS [1] is not released.

Like I said, are we failing to either collect of finalize JSStrings?  The finalizer of that JSString should be calling Release.

Honza, can you see whether we ever enter js_FinalizeStringRT for the string created in XPCConvert::NativeData2JS?  If so, do we enter FinalizeXPCOMUCString for the stringbuffer in question?

I'm assuming no to both of those...
(In reply to comment #14)
> This *could* be related to bug 614347.

That bug's patch doesn't help fixing this bug.
(In reply to comment #15)
> > And the second addref by JS [1] is not released.
> 
> Like I said, are we failing to either collect of finalize JSStrings?  The
> finalizer of that JSString should be calling Release.
> 
> Honza, can you see whether we ever enter js_FinalizeStringRT for the string
> created in XPCConvert::NativeData2JS?  

We don't.

> If so, do we enter FinalizeXPCOMUCString
> for the stringbuffer in question?
> 
> I'm assuming no to both of those...

Neither.
Sounds like we're either not garbage-collecting those strings or not finalizing them properly.
Do we leak other stuff in this case, i.e. nsGlobalWindow's?
(In reply to comment #19)
> Do we leak other stuff in this case, i.e. nsGlobalWindow's?

No.  When I open the page from a mochitest environment to have leak logs, I see no leaks in the final log.

Also, it behaves a bit different: I can see allocation of 256K about every 2 seconds, i.e. it's more jumpy.  Normally (a pure debug build running) I can see allocation of about 50K every 0.5 seconds.
Honza, if you leave the page, and wait a little bit, is the memory recovered?
(In reply to comment #21)
> Honza, if you leave the page, and wait a little bit, is the memory recovered?

Looks like it is.  I can see the missing Release() call on all allocated strings.
I assume in comment 2 you did "save as, complete"?
(In reply to comment #23)
> I assume in comment 2 you did "save as, complete"?

Yes, it is set default.
OK.  So if the stack in comment 5 is representative, the JS around that callsite is:

    this.checkFragment = function () {
        var hash = document.location.hash.substring(1);
        if (hash.length > 0 && hash !== this.oldQS) {
            var args = hash.split("/");
            this.oldQS = hash;
            var cmd = args.shift();
            cmd = "fragmentPump." + cmd;
            var temp = "";
            if (true == /page=send/gi.test(hash) || true == /page-=-send/gi.test(hash)) {
                showLoadingBox()
            }
            for (var i = 0; i < args.length; i++) {
                temp = temp + '"' + args[i] + '"';
                if (i < (args.length - 1)) {
                    temp = temp + ","
                }
            }
            var evStr = cmd + "(" + temp + ")";
            if (cmd == "fragmentPump.init" || cmd == "fragmentPump.test" || cmd == "fragmentPump.data" || cmd == "fragmentPump.show" || cmd == "fragmentPump.popup" || cmd == "fragmentPump.widget" || cmd == "fragmentPump.light") {
                var tempFun = eval("window." + cmd);
                if (tempFun) {
                    var tempFucn = new Function(evStr);
                    tempFucn()
                } else {}
            }
        }
    };

I assume that we do run GC here every so often, right?  Do we finalize those Function objects?
I can reproduce this in a clean profile (Current nightly on Win7x64 D3D9), just having that page open in a tab and looking at about:memory it grows constantly. Started from 35MB, opening the page it grew up to 65MB, then it started increasing up to 150MB, waiting a bit with the window idle brought back memory to about 100MB.
I only have about:memory and this page open on this clean profile.
Confirming comment 25.  The string in question is the 'hash' local var.
Also to complete the source code, above the lines in comment 25 is exactly the following:

fragmentPump = new
function () {
    this.fragTimer = "";
    this.oldQS = "";
    this.callBuffer = [];
    this.initRun = false;
    this.initialize = function () {
>        this.fragTimer = setInterval("fragmentPump.checkFragment()", 5)
    };
    this.startint = function () {
        setInterval(this.checkFragment.bind(this), 250)
    };

checkFragment is called from the line marked with >, i.e. 200 times a second...
Well, 100 times a second because we clamp it to a 10ms timer for now.

But ok.  Do we ever run GC in this case?
** PRODUCT DRIVERS PLEASE NOTE **

This bug is one of 7 automatically changed from blocking2.0:final+ to blocking2.0:.x during the endgame of Firefox 4 for the following reasons:

 - it was marked as a soft blocking issue without a requirement for beta coverage
blocking2.0: final+ → .x+
Summary: Constantly raising private bytes allocation on a web page → Constantly raising private bytes with setInterval("document.location.hash", 5);
Is this a dupe of bug 654399?
No longer blocks: mlk2.0
No longer blocks: mlk-fx5+
Whiteboard: [softblocker] → [softblocker][MemShrink:P2]
Status: NEW → RESOLVED
Closed: 13 years ago
Resolution: --- → DUPLICATE
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: