如何防止对象在v8中自动回收

贾努瓦

我需要在特定时间触发用户的回调函数,但是当触发回调函数时,该对象已被回收并且无法使用。有什么方法可以保存对象而不被回收?触发回调后,我想手动回收内存

LPVOID createCallbackFunc(void *lpMethod, Local<Function> *lpCB, Local<Context> *lpContext)
{
  /*
t_cb - 55                    - push rbp
014F0001- 48 8B EC              - mov rbp,rsp
014F0004- 48 81 EC 90010000     - sub rsp,00000190

014F000B- 48 89 4C 24 08        - mov [rsp+08],rcx
014F0010- 48 89 54 24 10        - mov [rsp+10],rdx
014F0015- 4C 89 44 24 18        - mov [rsp+18],r8
014F001A- 4C 89 4C 24 20        - mov [rsp+20],r9

014F001F- 48 B9 0000000000000000 - mov rcx,0000000000000000
014F0029- 48 BA 0000000000000000 - mov rdx,0000000000000000
014F0033- 4C 8D 44 24 08        - lea r8,[rsp+08]
014F0038- 4C 8D 4D 10           - lea r9,[rbp+10]

014F003C- 48 B8 F0ACAB14FE7F0000 - mov rax,user32.MessageBoxA
014F0046- FF D0                 - call rax

014F0048- 48 81 C4 90010000     - add rsp,00000190
014F004F- 48 8B E5              - mov rsp,rbp
014F0052- 5D                    - pop rbp
014F0053- C3                    - ret

*/

  string code_str = "55 48 8B EC 48 81 EC 90 01 00 00 48 89 4C 24 08 48 89 54 24 10 4C 89 44 24 18 4C 89 4C 24 20 48 B9 00 00 00 00 00 00 00 00 48 BA 00 00 00 00 00 00 00 00 4C 8D 44 24 08 4C 8D 4D 10 48 B8 F0 AC AB 14 FE 7F 00 00 FF D0 48 81 C4 90 01 00 00 48 8B E5 5D C3";

  vector<BYTE> code_bytes = byteStr2Bytes(code_str);

  memcpy_s(code_bytes.data() + 0x21, sizeof(uintptr_t), &lpCB, sizeof(uintptr_t));
  memcpy_s(code_bytes.data() + 0x2B, sizeof(uintptr_t), &lpContext, sizeof(uintptr_t));
  memcpy_s(code_bytes.data() + 0x3E, sizeof(uintptr_t), &lpMethod, sizeof(uintptr_t));

  auto newmem = VirtualAlloc(0, code_bytes.size() + sizeof(uintptr_t), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
  memcpy_s(newmem, code_bytes.size(), code_bytes.data(), code_bytes.size());
  return newmem;
}

BOOL cb_test(Local<Function> &cb, Local<Context> &context, uintptr_t *a, uintptr_t *b)
{
  // Will not print, and will give an error
  if (cb->IsFunction())
  {
    printf("xxx\n");
  }
  return FALSE;
};

void callback(const FunctionCallbackInfo<Value> &args)
{
  Isolate *isolate = args.GetIsolate();
  auto context = isolate->GetCurrentContext();

  auto cb = args[0].As<Function>();
  LPVOID addr = createCallbackFunc(&cb_test, &cb, &context);

  args.GetReturnValue().Set(Number::New(isolate, (uintptr_t)addr));
}

我当前的环境是Windows 10和Node.js 14.15.4

吉姆克

您的示例不完整(例如,该怎么createCallbackFunc做?),因此很难确定发生了什么,但是这里有一些需要考虑的一般要点:

  • 只要对象是可到达的,它们就不会被垃圾回收。这就是垃圾收集器的意义所在。
  • 您不能手动释放/回收由垃圾收集器管理的对象。
  • 我怀疑在当前情况下,问题在于处理。Local<...>是,顾名思义,意味着以良好定义的局部范围中使用。它的寿命与周围环境息息相关HandleScope如果createCallbackFunc尝试将其存放在某个地方,则可以预期Local它将很快失效(它没有说明最初指向的对象,也与垃圾收集器无关)。您可以在https://v8.dev/docs/embed上了解有关句柄及其生存期的更多信息
  • 如果您想要的是带有弱回调的弱引用,当对象被垃圾回收时将被调用,请查看“弱持久性”。请注意,无法保证何时确切地(或根本不)会调用此类回调(这只是“尽力而为”,但是例如,关闭时可能会被跳过),因此使用它们进行关键资源管理是一个坏主意。 。

更新问题后进行编辑:的来源createCallbackFunc揭示了两个问题:

  1. lpCB是指向堆栈分配对象的指针,memcpy_s(..., &lpCB, ..)您正在创建该指针地址副本那行不通;首先是因为lpCB它本身的寿命很短,其次是因为它所引用的堆栈分配cb(在函数中callback)同样是短暂的。因此,以这种方式创建的任何指针都会在callback函数返回后立即指向随机垃圾(问题的这一部分是标准的C ++,与V8或Node或GC或Windows或其他任何规范无关。)

  2. 正如我在较早的答案中所猜测的那样,您实际上是在尝试创建的长期副本Local使用aPersistent来完成。请阅读文档。

摘要:不要memcpy在上使用v8::Local

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

防止v8 :: Local值被垃圾回收

来自分类Dev

动态对象访问在V8中如何工作?

来自分类Dev

在V8中如何在内部表示对象?

来自分类Dev

如何获得v8函数以返回c ++对象?

来自分类Dev

将js对象映射到V8中的结构

来自分类Dev

V8中JavaScript对象的内存布局

来自分类Dev

不清楚V8垃圾回收

来自分类Dev

在 V8 中,未分配的 `Escape`d 句柄会立即成为垃圾回收的目标吗?

来自分类Dev

如何在 V8 中针对访问时间优化一小部分对象引用?

来自分类Dev

如何在V8中存储持久句柄?

来自分类Dev

如何在C ++中从V8调用Javascript函数

来自分类Dev

如何在OSX中替换Chromium的V8库?

来自分类Dev

如何在IBM MobileFirst V8中测试连接

来自分类Dev

从 JS (V8) 中 C++ 对象的引用调用函数

来自分类Dev

v8作用域如何工作?

来自分类Dev

V8如何管理其堆?

来自分类Dev

如何多次运行V8评估?

来自分类Dev

V8中的隐藏课程

来自分类Dev

V8中的Typeof和Expression *

来自分类Dev

V8中的Javascript等效项?

来自分类Dev

V8中的Javascript奇怪的性能

来自分类Dev

在V8中使用TerminateExecution

来自分类Dev

在v8中检测无限递归

来自分类Dev

Windows中的V8构建错误

来自分类Dev

V8中的JavaScript编译

来自分类Dev

如何在另一个线程中创建V8对象,然后将其复制回nodejs范围?

来自分类Dev

如何在另一个线程中创建V8对象,然后将其复制回nodejs范围?

来自分类Dev

如何防止自动排序对象数值属性?

来自分类Dev

V8 JavaScript对象与二叉树