在使用Embind的Javascript中,仅仅调用deleteLater()就足以避免内存泄漏吗

Is just calling deleteLater() enough to avoid memory leaks in Javascript with Embind?

本文关键字:泄漏 内存 deleteLater Embind Javascript 调用      更新时间:2023-10-16

我是一名长期的Java/C++程序员和新手Javascript程序员。我正在尝试用我以前用C++编写的类制作一个网络应用程序。

在我的Javascript web应用程序中,我使用Embind创建并使用最初用C++编码的类。在Embind文档页面上,它写道,

JavaScript代码必须显式删除它接收到的任何C++对象句柄,否则Emscripten堆将无限增长。

页面上的示例显示了创建的对象在使用后立即被删除:

var x=new Module.MyClass;x.method();x.delete();

在我的web应用程序中,我希望C++中的对象在网页的生命周期内保持不变。我希望能够按下页面上的按钮并更新我的对象的状态。如果我在脚本结束时.delete()对象,当我稍后尝试按下按钮时,它将不会持久存在。

在Embind示例Embind.test.js中,可以对新创建的对象调用.deleteLater():

var v=(new cm.ValHolder({})).deleteLater();

我的问题是,如果我在创建对象时简单地调用.deleteLater(),那么当应用程序运行完毕或页面关闭时,这是否足以删除对象?我正在努力避免无限期地增加堆或导致任何内存泄漏。

同样,我是Javascript的新手,所以请指出我是否遗漏了任何明显的内容,或者是否不了解Javascript中关于内存泄漏和指针的最佳实践。

如果我需要澄清什么,请告诉我。谢谢

参考:https://kripken.github.io/emscripten-site/docs/porting/connecting_cpp_and_javascript/embind.html#memory-管理

我走在同一条路上,真的没有具体的答案,但作为一名JS开发人员,我可以与之合作:

  • 对已删除的对象调用delete()会抛出一个丑陋的异常(无法从JS中捕获)。有一个未记录的方法来检查这一点:obj.isDeleted()。此外,当对象被"删除"时,obj.SS.count将为0
  • 在浏览器中,不删除对象肯定会破坏你的应用程序,但从C++开发人员的角度来看,这只会发生在文档的上下文中,所以只需重新加载页面,你就可以收回所有内存(这不是杀死浏览器的必要条件)
  • 当从C++代码中抛出异常时,如sigint、错误内存分配等,即使使用DISABLE_EXCEPTION_CATCHING或其他调试标志,似乎也无法捕获它们。Module.onAbort或类似程序也无法处理它们。因此,如果有人在程序抛出时处理deleteLater()注册的对象,则必须在C++端
  • 我看到没有关于delete()、isDeleted()deleteLater()的文档。我认为这些都是PR的好候选者