日期:2014-05-18  浏览次数:20676 次

有在java上用过rhino引擎的朋友吗,问个性能问题
要用java解析一些javascript代码,使用rhino引擎,过程大致如下


for(String expression : expressions) {
    Context cx = Context.enter();
    Scriptable scope = cx.initStandardObjects();
    Object result = cx.evaluateString(scope, expression, "s", 1, null);
}


大约有4w多条代码,执行到1w多的时候,就会报java.lang.OutOfMemoryError: PermGen space,请问有什么办法,帮忙解决一下,谢谢!

java.lang.OutOfMemoryError: PermGen space
at java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Class.java:2389)
at java.lang.Class.getConstructor0(Class.java:2699)
at java.lang.Class.newInstance0(Class.java:326)
at java.lang.Class.newInstance(Class.java:308)
at org.mozilla.javascript.optimizer.Codegen.createScriptObject(Codegen.java:89)
at org.mozilla.javascript.Context.compileImpl(Context.java:2394)
at org.mozilla.javascript.Context.compileString(Context.java:1335)
at org.mozilla.javascript.Context.compileString(Context.java:1324)
at org.mozilla.javascript.Context.evaluateString(Context.java:1076)

------解决方案--------------------
能解析一段释放一段不?这样搞,一次全部load到内存肯定会爆
------解决方案--------------------
不懂  以前好像靠同事弄过 忘了 真的不会
------解决方案--------------------
引用:
Quote: 引用:

能解析一段释放一段不?这样搞,一次全部load到内存肯定会爆


哦,括号里最后还少了一步 cx.exit(); 但是结果是一样的
前后还有些别的操作,比如查数据库,读本地xml,都没事,但是只要一解析js就爆,请问是什么道理


一直到 Java 7,类都是放在PermGen space里的,包括动态生成的类,而GC的很多时候不会卸载类。
(当然符合卸载条件的类,是会在某个时刻被卸载的,可惜那个某个时刻不由你控制)
而解析JS会产生大量的动态生成的类,尽管context exit了,那些被生成的类并没有马上被卸载。
所以越积越多,最后爆PermGen space。

你可以试试每次context exit时,让JVM 做个System.gc(),不行再sleep个几分钟,可能他就会把那些不用的类卸掉了。

Java 8 里PermGen space被取消了,类卸载会变得更可预测一点,期待一下吧。


------解决方案--------------------
最简单的办法,加大PermGen内存