Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

[v8] HandleScope结束后Local不释放?

  在函数中使用HandleScope后,即使不主动释放,它也会在函数运行结束后被作为局部变量释放,并调用相关的析构函数。但是在测试中函数结束后Local变量依然可以使用,而且即使主动调用了Close也只是把Close的参数放在了第一个Local变量上,为什么呢?
  先看下面这个测试
#include <node.h>
#pragma comment(lib,"node.lib")
using namespace v8;

Local<Value> func(){
  HandleScope scope; //为此函数开始一个新的HandleScope
  Local<Value> s=String::New("test"); //创建一个句柄
  return s; //函数结束时HandleScope会被析构,Local句柄会被回收吧?
};

int main(void){
  HandleScope scope;
  Local<Value> s=func(); //函数结束后依然可以使用原来的Local句柄
  String::AsciiValue v(s); //字符串句柄中获取Ascii值
  printf("%s\n",*v); //局部定义的数据可以照常输出“test”
  return 0;
}

NODE_MODULE(test,main);
  这个结果很简单,我就不截图了。我们要考虑的是,难道函数运行结束HandleScope不会析构吗?那我们再做另一个测试
#include <node.h>
#pragma comment(lib,"node.lib")
using namespace v8;

Local<String> func(int i){
  HandleScope scope; //为此函数开始一个新的HandleScope
  Local<String> s[]={
    String::New("s1"), //创建一个句柄
    String::New("s2")  //再创建一个句柄
  };
  scope.Close(Undefined()); //手动调用Close,这不可能失效了吧?
  return s[i]; //这里是在句柄回收后再返回
};

int main(void){
  //把它们输出看看
  String::AsciiValue s1(func(0));
  printf("%s\n",*s1);
  String::AsciiValue s2(func(1));
  printf("%s\n",*s2);
  return 0;
}

NODE_MODULE(test,main);

  这个结果是不是很诡异?首先,被释放掉的话结果应该是null,结果是undefined意味着func函数中的第一个句柄变成了HandleScope结束后在外层HandleScope创建的新句柄。然后s2为什么没被释放掉?难道手动调用Close也不能释放Local?
  HandleScope只是回收句柄,而释放数据是GC的工作。句柄被回收掉以后可以重复利用,在调用Close后产生的新句柄刚好再次分配给回收后需要创建的新句柄,所以s1就指向了Undefined的数据部分。至于s2没有被释放是因为句柄只是在HandleScope中被回收,我们访问s2是通过s这个数组变量,在GC调用之前这个变量依然可以访问的话就可以拿到旧数据。
  HandleScope大概就是这么一个行为,虽然接口还有提供更多方法,但它的本质工作只是管理句柄而已。
网名:
54.144.24.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^