Closed
Bug 197682
Opened 22 years ago
Closed 22 years ago
Memory leak via static filed in generated bytecode
Categories
(Rhino Graveyard :: Compiler, defect)
Tracking
(Not tracked)
VERIFIED
FIXED
1.5R5
People
(Reporter: igor, Assigned: norrisboyd)
Details
Attachments
(4 files)
Currently Rhino optimizer with optimization level set to 1 or higher adds a
static fields to classes representing compiled script functions to perform
function call optimization.
These static fields holds references to script runtime objects and as long as
the loaded classes together with their static fields are not garbage collected,
the runtime structures will remain in JVM memory. It is not a problem in typical
situations where script is created and immediately executed since in such cases
generated classes can be GCed after script execution allowing to GC the runtime
as well.
But in the case of JavaScript compiler this is no longer true since then
generated classes representing a compiled script are stored as class files and
can be loaded via system class loader which means that object stored in static
fields will never be garbage collected. It leaks references to script runtime
structures and if script is loaded more then once, it will disable the
optimization altogether since the static fields will hold the reference for
wrong runtime structures.
P.S. From now I will use igor@fastmail.fm for mozilla.org and other
communications outside my work since due to various reorganization at work
igor@icesoft.no and igor@icesoft.com may or may not work, a provider that I used
for private mail (igor at mir2 org) made an "improvement" that stopped mail
working for days and igor3@apochta.com that I sometime used for various mail
lists to prevent spam is no longer necessary since I finally got good enough
spam filters.
Reporter | ||
Comment 1•22 years ago
|
||
Reporter | ||
Comment 2•22 years ago
|
||
Reporter | ||
Comment 3•22 years ago
|
||
Steps to reproduce the problem:
1. Compile the script from the first attachment by JavaScript compiler with an
optimization level set to 1 or higher:
java -classpath js.jar org.mozilla.javascript.tools.jsc.Main -opt 1 script.js
2. Compile a Java program form the second attachment:
javac -classpath .:js.jar StaticFieldProblem.java
where . is included to the classpath so javac finds classes generated by
JavaScript compiler.
The program instantiate and execute an instance of the class script created by
JavaScript compiler and then calls the garbage collector explicitly to see if an
instance of CustomScope which the program as a scope object is finalized.
3. Run StaticFieldProblem:
javac -classpath .:js.jar StaticFieldProblem
It currently prints
finalizeCount=0
indicating that a reference to CustomScope is not GCed.
Reporter | ||
Comment 4•22 years ago
|
||
The static fields generated by the compiler store references to objects
representing JavaScript functions that are targets of direct call optimization.
They are used to make sure during optimized calls that a function reference
still points to the original function object. For example, in the script from
the first attachment:
function a(x)
{
b(x);
}
function b(x)
{
return x == 0;
}
the code generated for a() to call b() checks if the property b still holds the
original function object and if it does, a() will use an optimized calling
conversion to call b().
The patch replaces static fields by an instance fields in the class
representing the main script object. This is quite significant change since it
adds code to store/query a field that refers to the main class to each function
class and changes the way the direct fields are initialized. Still the patch
itself is not that big since during the work on the patch I found that some of
refactoring that are necessary for the patch is make sense to apply on its own
and that part is already in CVS.
Reporter | ||
Comment 5•22 years ago
|
||
I commited the patch and now the test case prints what it should:
finalizeCount=1
Status: NEW → RESOLVED
Closed: 22 years ago
Resolution: --- → FIXED
Comment 6•22 years ago
|
||
Marking Verified.
I also get 'finalizeCount=1' as the output of the steps to reproduce
given in Comment #3.
However, that's what I got before the patch was committed, as well!
Is it possible the results are machine-dependent?
Status: RESOLVED → VERIFIED
Reporter | ||
Comment 7•22 years ago
|
||
Phil, did you re-run the JavaScript compiler with optimization set to 1 against
the scripts when you run the test with and without patch? It is strange that you
get that finalizeCount=1 in both cases. Without the patch the script compiler
has to produce the code with static fields that are never cleared and AFAIK
objects reachable through such fields should not be subject of garbage
collection since JDK 1.1 in this case.
Comment 8•22 years ago
|
||
Igor: you're right! I must have made some mistake the other day. When
I try the testcase today against rhino1_5R4pre (i.e. before the fix),
I get finalizeCount=0 just like you did.
Sorry for the trouble. I will attach my results below, verifying
that the bug is fixed -
Comment 9•22 years ago
|
||
Reporter | ||
Comment 10•22 years ago
|
||
Thanks Phil!
You need to log in
before you can comment on or make changes to this bug.
Description
•