Closed Bug 71306 Opened 19 years ago Closed 10 years ago

Windows memory usage keeps increasing when enablePrivilege xpcom methods being called, specially when the method returns string or array.

Categories

(Core :: XPCOM, defect, P2, critical)

x86
Windows NT
defect

Tracking

()

RESOLVED INCOMPLETE
Future

People

(Reporter: wli, Unassigned)

References

()

Details

(Keywords: perf)

Attachments

(2 files)

From Bugzilla Helper:
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 4.0)
BuildID:    0.7

<center><b><font size=+2>XPConnect Memory Leaking Test</font></b>
</center>
<script>
/* to use nsSample.js version, use "@mozilla.org/jssample;1" */
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var sample = Components.classes["@mozilla.org/sample;1"].createInstance();
sample = sample.QueryInterface(Components.interfaces.nsISample);
var count=0;
function onTimer(){
	set();
	get();
	if(count<2000)
		setTimeout("onTimer()", 100);
}
function get(){
  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
  var field = document.getElementById('Value');
  field.value = sample.value;
}
function set(){
  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
  var field = document.getElementById('Value');
  sample.value = count ;   //+ ": " + field.value;
  count++;
}
</script>
<form name="form">
<input type="button" value="Click me to start counting..." onclick="onTimer();">
<input type="text" id="Value">
<form>


Reproducible: Always
Steps to Reproduce:
1. goto local file "file:///c:/temp/sample.html";
2. click on button;
3. 

Actual Results:  After count 2000 times, Windows memory useage could be 
increased more than 2MB.

Expected Results:  JS_GC() function should clear all memory allocated in xpcom 
implementation.
What do you see if you *don't* call through xpconnect, but do all the other 
stuff on this timeout? This could just be a DOM issue not calling gc often 
enough when running timeouts?
I have tried without xpconnect call. The result is that the speed of memory 
consuming was pretty much slower than the one with xpconnect call. By the way,
in implementation of my real XPCOM object, I forced it to call JS_GC but it 
didn't make sense to prevent memory from increasing. Other than JS_GC, do we 
have other way to force cleaning up of memory used by JavaScript runtime? 
Thanks.
The comparable way to take xpconnect out of the picture is to replace the 
xpconnect calls with calls that make a copy of the string each time get of 
sample.value would have been called. This would be more comparable since 
xpconnect has to do this string copying. The strings xpconnect is making copies 
of are themselves JavaScript 'gcthings' and live until gc happens.

I trully suspect that xpconnect is not a meaningful part of your problem here. 
I think the issue in your testcase is how often JS_GC happens when timeouts are 
concerned.

I can't really comment on what was happening in your 'real' xpcom object. It 
may or may not have anything to do with the case you show here. But JS_GC is 
*the* way to make JS do its garbage collection. I have no way of knowing if 
other leaks were occuring in your code. If you are making direct calls to the 
JSAPI then you *might* have been causing other non-gc'd objects to leak. I can't 
say.
I do agree with you that xpconnect is a meaningful part of in my problem. I 
guess there is some kind of reference in xpconnect wrapper or somewhere else
 to prevent allocated memory from being gc'ed. In my test case, I use the 
sample xpcom plugin with Mozilla source code so that anybody can redo the test 
by himself.
As to my "real" xpcom project, just ignore it.
No. XPConnect does not do anything to keep the JS gcthings allocated as 
temporaries in this case from being gc'd. As a test I added a printf to js_GC to 
allow me to see when gc was actually happening. I ran your case and 
a modification to it that does not actually call xpconnect (but does do string 
copying of JSStrings to simulate the work that xpconnect has to do). In both 
cases during the course of the 2000 timer callbacks the gc did not run once.

This is just an issue of gc scheduling in setTimer callbacks. That is a DOM 
problem. Yes, xpconnect calls create temporary JS gcthings, but any JS code 
running in response to the timer callback might do that. The flow of your test 
has to do with JS running in the DOM world and the DOM code's scheduling of 
JS_GC calls.
For instance, try:

<script>
var count=0;
var foo = "some text";
function onTimer(){
        foo = foo+" - this is more text ";
        set();
        if(count<2000)
                setTimeout("onTimer()", 100);
}
function set(){
  var field = document.getElementById('Value');
  field.value = count++;
}

</script>
<form name="form">
<input type="button" value="Click me to start counting..." onclick="onTimer();">
<input type="text" id="Value">
<form>
We checked into xpconnect code, the memory allocated in nsSample::GetValue() 
function is freed there.  We actually added two more functions Get/SetLong() to 
avoid strdup text string, and called JS_GC() directly, the leak is still 
there.   
I may agree this may be GC sheduling issue,  but compared with or without xpcom 
object, the xpcom case caueses much more leaking than pure js object(your 
sample).  So I doubt that xpconnect (during mashelling?) may allocate some 
memory that GC cannot handle in real-time.  
Can you assign this bug to GC people if necessary?  Thanks.
What's status of this bug?  If this problem can't be solved, it'll really 
prevent us from further development of XPCom projects...

Alan
This is misassigned, it seems to me.  Either it's a bug jst can address with
better GC scheduling, or it's a dup of bug 66381.  jst, what do you think?

/be
Assignee: scc → jst
I've had no time to look into what's happening here, I'd love to fix this, but I
don't know where the problem is. I could easily make the timer code trigger
JS_GC() or JS_MaybeGC() every n timeouts (one could easily try that by inserting
a JS_GC() call in GlobalWindowImpl::RunTimeout()) but if that doesn't fix the
problem, then we need to know what's leaking, could someone run this in Purify,
or run with the refcount logging on, or some of the other tools that are out there?
The statement in my original test 
code, "netscape.security.PrivilegeManager.enablePrivilege
("UniversalXPConnect");", may be the critical one which contributs
large part of memory usage. The possible reason is that in 
nsBasePrincipal::SetCapability function, when the second parameter
annotation is NULL, the runtime will construct a empty hashtable
and store the new object to mAnotations member of nsBasePrincipal instance.
But because of some kind of cause (anotation of stack frame is fred at
js_Interpret function's JSOP_RETURN case?) everytime the passed second 
parameter from nsScriptSecurityManager::EnableCapability will be NULL. The  
result is that the mAnotations will store more and more hashtable objects 
and not free them until nsBasePrincipal instance's destructor is called. If 
there is just a few calls to SetCapability, every thing looks fine, otherwise, 
pretty much memory will be used to store those hashtable objects. 
Call stack is like:
nsScriptSecurityManager::EnableCapability() line 1203
netscape_security_enablePrivilege() line 214 + 27 bytes
js_Invoke() line 784 + 23 bytes
js_Interpret() line 2607 + 15 bytes
js_Execute() line 956 + 13 bytes
JS_EvaluateUCScriptForPrincipals() line 3258 + 27 bytes
nsJSContext::EvaluateString() line 603 + 68 bytes
GlobalWindowImpl::RunTimeout() line 3826 + 97 bytes
nsGlobalWindow_RunTimeout() line 4104 + 15 bytes

Thanks, Wen
Cc:ing mstoltz, Mitchell, please read the last comment, should something be done
about that?
I'm convinced.  Confirming and reassigning.

/be
Assignee: jst → mstoltz
Status: UNCONFIRMED → NEW
Ever confirmed: true
Hmm, Norris's code. I'll take a look.
Status: NEW → ASSIGNED
Sounds like this is only a problem if a script calls enablePrivilege many times,
which is not common, so I don't think this is an RTM stopper. It's an RTM
nice-to-have.
Priority: -- → P4
Target Milestone: --- → mozilla0.9.3
Priority: P4 → P2
milestone 0.9.4
Target Milestone: mozilla0.9.3 → mozilla0.9.4
Moving to 0.9.5.
Target Milestone: mozilla0.9.4 → mozilla0.9.5
time marches on. Retargeting to 0.9.6.
Target Milestone: mozilla0.9.5 → mozilla0.9.6
Less important bugs retargeted to 0.9.9
Target Milestone: mozilla0.9.6 → mozilla0.9.9
Moving Netscape owned 0.9.9 and 1.0 bugs that don't have an nsbeta1, nsbeta1+,
topembed, topembed+, Mozilla0.9.9+ or Mozilla1.0+ keyword.  Please send any
questions or feedback about this to adt@netscape.com.  You can search for
"Moving bugs not scheduled for a project" to quickly delete this bugmail.
Target Milestone: mozilla0.9.9 → mozilla1.2
Target Milestone: mozilla1.2alpha → Future
I think I can safely say that the problem is not relegated to just "tabs" as I've seen the same behavior when opening and closing Mozilla windows.  

I do a good bit of aftermarket buy-n-sell on ebay and I will regularly open and close 30-50 windows every other evening (searching for new parts/pieces, etc.).  I too have noticed that memory utilization continues to clime, and is not recovered until Mozilla is shut down and the process terminates.  (I run with Window NT's Task Manager up all the time... so its easy to see this happen.) If I neglect to shut down and restart mozilla, the system will walk itself right out of (physical and virtual) memory.

No - I'm not running with quick launch enabled.
No - its not limited to Tabs... it happens in both tabs and windows.
This happens on Linux & Windows NT/2000, please change platform to all.
Depends on: 66381
I don't think this bug depends on bug 66381.  Please don't set a dependency
without saying why you do think it so depends.

/be
No longer depends on: 66381
I have no idea if what I noticed is related to this bug.
However symptom seems to be identical. So, to helping you, Mozilla
developers, I attached 2 screenshot.
This one is right after the Mozilla Suite is launched.
Status : Only 1 Window is open
Keywords: perf
QA Contact: kandrot → nobody
Assignee: security-bugs → nobody
Status: ASSIGNED → NEW
QA Contact: nobody → xpcom
(In reply to comment #21)
> I think I can safely say that the problem is not relegated to just "tabs" as
> I've seen the same behavior when opening and closing Mozilla windows.  

per comment 15 this is related to enablePrivilege (if the analysis is correct) of the testecase in comment 0, and is not a general memory usage problem.

Perhaps Wen Li can confirm.
Summary: Windows memory usage keeps increasing when xpcom methods being called, specially when the method returns string or array. → Windows memory usage keeps increasing when enablePrivilege xpcom methods being called, specially when the method returns string or array.
Status: NEW → RESOLVED
Closed: 10 years ago
Resolution: --- → INCOMPLETE
You need to log in before you can comment on or make changes to this bug.