Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

how to avoid out of memory with infinite loop

61 views
Skip to first unread message

Rhino user

unread,
Feb 4, 2009, 2:59:22 PM2/4/09
to
My script looks like this -
var i = "0";

init("A qucik brown fox jumps over the lazy dog A qucik brown fox
jumps over the lazy dog A qucik brown fox jumps over the lazy dog A
qucik brown fox jumps over the lazy dog A qucik brown fox jumps over
the lazy dog A qucik brown fox jumps over the lazy dog A qucik brown
fox jumps over the lazy dog A qucik brown fox jumps over the lazy dog
A qucik brown fox jumps over the lazy dog A qucik brown fox jumps over
the lazy dog A qucik brown fox jumps over the lazy dog A qucik brown
fox jumps over the lazy dog A qucik brown fox jumps over the lazy dog
A qucik brown fox jumps over the lazy dog A qucik brown fox jumps over
the lazy dog A qucik brown fox jumps over the lazy dog A qucik brown
A qucik brown fox jumps over the lazy dog A qucik brown fox jumps over
the lazy dog A qucik brown fox jumps over the lazy dog A qucik brown
fox jumps over the lazy dog A qucik brown fox jumps over the lazy dog
A qucik brown fox jumps over the lazy dog A qucik brown fox jumps over
the lazy dog A qucik brown fox jumps over the lazy dog A qucik brown
fox jumps over the lazy dog A qucik brown fox jumps over the lazy dog
A qucik brown fox jumps over the lazy dog A qucik brown fox jumps over
the lazy dog A qucik brown fox jumps over the lazy dog ");

function init(s)
{
while(i=="0")
s+=s;
}

I get
ava.lang.OutOfMemoryError: Java heap space
at java.lang.String.concat(String.java:1831)
at org.mozilla.javascript.ScriptRuntime.add(ScriptRuntime.java:2296)
at org.mozilla.javascript.gen.c3._c1(externalScript:11)
at org.mozilla.javascript.gen.c3.call(externalScript)

How can I avoid it?
Thanks
-Anupama

Marcello Bastéa-Forte

unread,
Feb 5, 2009, 1:32:20 PM2/5/09
to Rhino user, dev-tech-js-...@lists.mozilla.org
you could catch the exception:
try {
... execute javascript ...
} catch (OutOfMemoryError ex) {
... do what you want to do ...
}

Marcello

> _______________________________________________
> dev-tech-js-engine-rhino mailing list
> dev-tech-js-...@lists.mozilla.org
> https://lists.mozilla.org/listinfo/dev-tech-js-engine-rhino
>

Patrick Dobbs

unread,
Feb 5, 2009, 2:03:56 PM2/5/09
to
I think you need to define a Context (in Java) which checks that scripts
are behaving sensibly:

http://www.mozilla.org/rhino/apidocs/org/mozilla/javascript/ContextFactory.html

Anupama Joshi

unread,
Feb 6, 2009, 12:23:35 AM2/6/09
to Patrick Dobbs, dev-tech-js-...@lists.mozilla.org
I implemented the context factory .
I still get
Java heap space

!!!!![ERROR] java.lang.OutOfMemoryError: Java heap space
at java.lang.String.concat(String.java:1831)
at org.mozilla.javascript.Interpreter.do_add(Interpreter.java:4019)
at
org.mozilla.javascript.Interpreter.interpretLoop(Interpreter.java:2761)
at org.mozilla.javascript.Interpreter.interpret(Interpreter.java:2251)
at
org.mozilla.javascript.InterpretedFunction.call(InterpretedFunction.java:161)
at
com.adobe.internal.pdftoolkit.services.javascript.security.JSSecurityController$1.run(JSSecurityController.java:96)
at java.security.AccessController.doPrivileged(Native Method)
at
com.adobe.internal.pdftoolkit.services.javascript.security.JSSecurityController.callWithDomain(JSSecurityController.java:100)
at org.mozilla.javascript.Interpreter.interpret(Interpreter.java:2240)
at
org.mozilla.javascript.InterpretedFunction.call(InterpretedFunction.java:161)
at
org.mozilla.javascript.ContextFactory.doTopCall(ContextFactory.java:340)
at
com.adobe.internal.pdftoolkit.services.javascript.MyFactory.doTopCall(MyFactory.java:84)
Can I avoid the exception?
Thanks
-Anupama

Priit Liivak

unread,
Feb 6, 2009, 2:42:20 AM2/6/09
to dev-tech-js-...@lists.mozilla.org
There is an example to avoid scripts running more than 10sec. You can use MBean to monitor heap space and if out of memory is near you throw an error. With your example the heap can grow pretty fast so you need to make Rhino runtime to call observeInstructionCount more often than once for each 10000 bytecode instructions. You can also take a look at this: http://www.javaspecialists.co.za/archive/Issue092.html for OutOfMemoryError Warning System.

Infinite loop is easier to detect if memory usage does not increase so much.
Given that you use MBean to monitor memory usage then, if several scripts are executed then it is not guaranteed that the one causing the leak is stopped. Memory consumption has to be monitored on thread level but I'm not sure that's possible.

Rhino user

unread,
Feb 23, 2009, 10:49:31 PM2/23/09
to
On Feb 5, 11:42 pm, Priit Liivak <Priit.Lii...@webmedia.ee> wrote:
> There is an example to avoid scripts running more than 10sec. You can use MBean to monitor heap space and if out of memory is near you throw an error. With your example the heap can grow pretty fast so you need to make Rhino runtime to call observeInstructionCount more often than once for each 10000 bytecode instructions. You can also take a look at this:http://www.javaspecialists.co.za/archive/Issue092.htmlfor OutOfMemoryError Warning System.

> _______________________________________________
> dev-tech-js-engine-rhino mailing list
> dev-tech-js-engine-rh...@lists.mozilla.orghttps://lists.mozilla.org/listinfo/dev-tech-js-engine-rhino

I implemented context and contextfactory. And tried to play around
with the instruction count and stack depth . I also adjusted the
time. This script quickly eats up memory. Only if the time is
adjusted to like 100 ms then it throws error rather than oom.
here is my code , pl. let me know what more can I do. Next I am going
to try the MxBeans. before that , i want to know if anything with
Rhino can do it.
public class MyFactory extends ContextFactory
{

// Custom Context to store execution time.
private static class MyContext extends Context
{
long startTime;

MyContext(ContextFactory f ){
super(f);
}
protected void observeInstructionCount(Context cx, int
instructionCount)
{

MyFactory f = (MyFactory) getFactory();
f.observeInstructionCount(this, instructionCount);
System.out.println("instructionCount in mycontext "+
instructionCount);
long currentTime = System.currentTimeMillis();
if (currentTime - startTime > .1*10) {
// More then 10 seconds from Context creation time:
// it is time to stop the script.
// Throw Error instance to ensure that script will
never
// get control back through catch or finally.
throw new java.lang.ThreadDeath();
//return;
}
}
}

static {
// Initialize GlobalFactory with custom factory
ContextFactory.initGlobal(new MyFactory());
}

// Override makeContext()
protected Context makeContext()
{
MyContext cx = new MyContext(this);
cx.setClassShutter(new ClassShutter() {
public boolean visibleToScripts(String className) {
return className.startsWith("org.mozilla.javascript") ||
className.startsWith( "java.lang.Object");
}
});
if(controller != null)
cx.setSecurityController(controller);
System.out.println("setOptimizationLevel "+
cx.getOptimizationLevel());
cx.setOptimizationLevel(-1);
cx.setMaximumInterpreterStackDepth(1);
// Make Rhino runtime to call observeInstructionCount
// each 10000 bytecode instructions
System.out.println("getMaximumInterpreterStackDepth "+
cx.getMaximumInterpreterStackDepth());
cx.setInstructionObserverThreshold(10);

return cx;
}
JSSecurityController controller = null;
public void setSecurityController(JSSecurityController
SecController){
controller = SecController;
}
// Override hasFeature(Context, int)
public boolean hasFeature(Context cx, int featureIndex)
{
// Turn on maximum compatibility with MSIE scripts
switch (featureIndex) {
case Context.FEATURE_NON_ECMA_GET_YEAR:
return true;

case Context.FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME:
return true;

case Context.FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER:
return true;

case Context.FEATURE_PARENT_PROTO_PROPRTIES:
return false;
}
return super.hasFeature(cx, featureIndex);
}

// Override observeInstructionCount(Context, int)
protected void observeInstructionCount(Context cx, int
instructionCount)
{

MyContext mcx = (MyContext)cx;
ContextFactory f = mcx.getFactory();
//f.observeInstructionCount(mcx, instructionCount);
// System.out.println("instructionCount "+ instructionCount);
long currentTime = System.currentTimeMillis();
if (currentTime - mcx.startTime > 5*1000) {
// More then 10 seconds from Context creation time:
// it is time to stop the script.
// Throw Error instance to ensure that script will never
// get control back through catch or finally.
throw new java.lang.ThreadDeath();
//return;
}
}

// Override doTopCall(Callable, Context, Scriptable,Scriptable,
Object[])
protected Object doTopCall(Callable callable,
Context cx, Scriptable scope,
Scriptable thisObj, Object[] args)
{
MyContext mcx = (MyContext)cx;
mcx.startTime = System.currentTimeMillis();

return super.doTopCall(callable, cx, scope, thisObj, args);
}

}

Rhino user

unread,
Feb 25, 2009, 5:55:22 PM2/25/09
to
On Feb 23, 7:49 pm, Rhino user <anupama.jo...@gmail.com> wrote:
> On Feb 5, 11:42 pm, Priit Liivak <Priit.Lii...@webmedia.ee> wrote:
>
>
>
> > There is an example to avoid scripts running more than 10sec. You can use MBean to monitor heap space and if out of memory is near you throw an error. With your example the heap can grow pretty fast so you need to make Rhino runtime to call observeInstructionCount more often than once for each 10000 bytecode instructions. You can also take a look at this:http://www.javaspecialists.co.za/archive/Issue092.htmlforOutOfMemoryError Warning System.

Any ideas? solutions?

Rapha

unread,
Mar 15, 2009, 8:25:02 PM3/15/09
to
What are you trying to do with this script?

It looks like you're just making the string 's' longer and longer
forever. Eventually, the system is not going to have enough memory
available to accommodate that. That's when you'll get the
OutOfMemoryError.

0 new messages