我正在使用Qt 5.12将一个应用程序放在一起,用户将加载通过其API与应用程序交互的JS脚本。这些脚本被捆绑到"项目"(即多个相互依赖的JS模块)中,并且任何时候我都希望只有一个项目加载到JS引擎中,因此如果用户加载不同的项目,我希望清理以前的上下文。
根据文档,我假设如果我只是删除 QJSEngine 对象并创建一个新对象,这将允许我创建一个新的 JS 上下文。
QJSEngine* jsEngine = new QJSEngine();
// Load JS modules and run code...
jsEngine->collectGarbage();
delete jsEngine;
jsEngine = new QJSEngine();
// Load new JS modules...
当我尝试运行此代码时,我在delete jsEngine
处收到访问冲突异常。这真的很奇怪,因为文档本身指出
在 QJSEngine 销毁期间,不会从持久化 JS 堆中收集垃圾。如果需要释放所有内存,请在销毁 QJSEngine 之前手动调用 collectGarbage 。
对我来说,这意味着我应该能够做到这一点。有人有什么想法吗?提前感谢!
好吧,事实证明我是一个假人,忘记包含一个重要的细节:我的应用程序还使用QJSEngine::newQObject
向 JS 引擎公开我的"JavaScript 接口"对象,所以我几乎只是在重现这个问题。
解决方案完全相同:使用QQmlEngine::setObjectOwnership
使问题消失。
确保你没有任何剩余的QJSValues。
或者,如果您只想清理状态。清除 QJSEngine::globalObject(),或者只是避免使用根 JS 状态,这样项目之间就不会泄漏任何内容。