准备 Nashorn 引擎的 Apache Commons 池的有效方法
Efficient Way to Prepare an Apache Commons Pool of Nashorn Engines
我正在使用 Apache Commons Pool to create a pool of Nashorn engines. On application start I call preparePool()
预热 minIdle
个实例到 eval()
所有脚本到引擎中,以便它准备好响应对 invokeFunction()
的调用立即。
热身
@Override
public NashornScriptEngine create() {
// ...
try {
engine.eval(asset1);
engine.eval(asset2);
engine.eval(asset3);
} // ...
return engine;
}
根据池大小和预加载脚本的复杂性,这需要相当长的时间。
问题
我可以只预热一个实例并将其安全地克隆到 minIdle
个实例吗?
是否可以安全地序列化和持久化已创建实例的克隆? (这将允许维护一个引擎缓存,只需要在其中一项资产发生变化时失效)
相关资源(将在适当的时候更新此部分)
- SO: Clone Entire JavaScript Engine
Nashorn 的引擎实例既不可克隆也不可序列化。不过,我建议您使用单个引擎实例并使用 ScriptEngine.createBindings()
创建多个 Bindings
对象并将它们合并。您显然需要通过调用 ScriptEngine.eval(String|Reader, Bindings)
方法来初始化每个绑定。 (您还可以使用 ScriptContext
对象而不仅仅是 Bindings
;它们实际上是绑定元组和 out/err 流。)
使用单个 ScriptEngine
的好处是代码共享。将同一个脚本评估为多个绑定仍然只会编译脚本一次(如果您使用 Compilable
接口)并且所有函数对象的代码将由相同的编译字节码表示。
我正在使用 Apache Commons Pool to create a pool of Nashorn engines. On application start I call preparePool()
预热 minIdle
个实例到 eval()
所有脚本到引擎中,以便它准备好响应对 invokeFunction()
的调用立即。
热身
@Override
public NashornScriptEngine create() {
// ...
try {
engine.eval(asset1);
engine.eval(asset2);
engine.eval(asset3);
} // ...
return engine;
}
根据池大小和预加载脚本的复杂性,这需要相当长的时间。
问题
我可以只预热一个实例并将其安全地克隆到
minIdle
个实例吗?是否可以安全地序列化和持久化已创建实例的克隆? (这将允许维护一个引擎缓存,只需要在其中一项资产发生变化时失效)
相关资源(将在适当的时候更新此部分)
- SO: Clone Entire JavaScript Engine
Nashorn 的引擎实例既不可克隆也不可序列化。不过,我建议您使用单个引擎实例并使用 ScriptEngine.createBindings()
创建多个 Bindings
对象并将它们合并。您显然需要通过调用 ScriptEngine.eval(String|Reader, Bindings)
方法来初始化每个绑定。 (您还可以使用 ScriptContext
对象而不仅仅是 Bindings
;它们实际上是绑定元组和 out/err 流。)
使用单个 ScriptEngine
的好处是代码共享。将同一个脚本评估为多个绑定仍然只会编译脚本一次(如果您使用 Compilable
接口)并且所有函数对象的代码将由相同的编译字节码表示。