要用到 vm 去跑很多代码, 而且会是长久存在于内存当中的实例, 并且随着服务运行可能还要缓慢增加 vm 的实例数量. 这种情况下是否会可能会由于 vm 什么问题影响性能甚至破坏服务的稳定性呢?
你调用 vm.runInContext时,第二个参数必须传入contextifiedSandbox 所以肯定要在调用前做一个createContext的操作,比如:
var sandbox = { foo: 'bar' }; var context = vm.createContext(sandbox); result = vm.runInContext( 'baz = foo; this.typeofProcess = typeof process; typeof Object;', context );
但是这里有一个比较危险的地方:createContext函数 这个函数调用了binding层的c++的一些代码,具体实现在node_contexttify.cc中 它会检测你每次传入的sandbox是否有_contextifyHidden属性,如果没有,调用ContextifyContext类给你new一个 但是偏偏这个类是很危险的,因为这个类定义了三个Persistent类型而不是Local类型的Handle:
Persistent<Object> sandbox_; Persistent<Context> context_; Persistent<Object> proxy_global_;
Persistent类型的handle,不受HandleScope的管理,GC无法回收。(除非使用MakeWeak弱化其引用) 这样大量的vm.createContext(js对象)被执行的话,就会造成内存泄漏
所以我觉得,只要把每一个sandbox(自己定义的js对象)写到类似全局的地方,而不是每个用户请求都重新创建一个sandbox对象的话,大量使用vm.runInContext应该也没有问题吧
@hyj1991 虽然这么说, 开始 sandbox 既然是 context 要用到的数据, 我就不好写在全局了, 还只能每次都写一个.
@jiyinyiyong 其实蛮好奇,什么样的场景会用到vm模块,哈哈
@hyj1991 这货用了 https://github.com/vuejs/vue/blob/next/src/server/run-in-vm.js
CNode 社区为国内最专业的 Node.js 开源技术社区,致力于 Node.js 的技术研究。
你调用 vm.runInContext时,第二个参数必须传入contextifiedSandbox 所以肯定要在调用前做一个createContext的操作,比如:
但是这里有一个比较危险的地方:createContext函数 这个函数调用了binding层的c++的一些代码,具体实现在node_contexttify.cc中 它会检测你每次传入的sandbox是否有_contextifyHidden属性,如果没有,调用ContextifyContext类给你new一个 但是偏偏这个类是很危险的,因为这个类定义了三个Persistent类型而不是Local类型的Handle:
Persistent类型的handle,不受HandleScope的管理,GC无法回收。(除非使用MakeWeak弱化其引用) 这样大量的vm.createContext(js对象)被执行的话,就会造成内存泄漏
所以我觉得,只要把每一个sandbox(自己定义的js对象)写到类似全局的地方,而不是每个用户请求都重新创建一个sandbox对象的话,大量使用vm.runInContext应该也没有问题吧
@hyj1991 虽然这么说, 开始 sandbox 既然是 context 要用到的数据, 我就不好写在全局了, 还只能每次都写一个.
@jiyinyiyong 其实蛮好奇,什么样的场景会用到vm模块,哈哈
@hyj1991 这货用了 https://github.com/vuejs/vue/blob/next/src/server/run-in-vm.js