zoukankan      html  css  js  c++  java
  • Google V8编程详解(三)Handle & HandleScope

    上一章简单的演示了一个Helloworld Demo。里面涉及到了V8的一些基本类型和概念,本章将围绕这个Demo对V8的基本类型和相关概念进行讲解。

    这里还是先把Demo贴出来便于后面分析:

    1. #include <v8.h>  
    2.   
    3. using namespace v8;  
    4. int main(int argc, char* argv[]) {  
    5.   
    6.   // Create a stack-allocated handle scope.  
    7.   HandleScope handle_scope;  
    8.   
    9.   // Create a new context.  
    10.   Persistent<Context> context = Context::New();  
    11.   
    12.   // Enter the created context for compiling and  
    13.   // running the hello world script.  
    14.   Context::Scope context_scope(context);  
    15.   
    16.   // Create a string containing the JavaScript source code.  
    17.   Handle<String> source = String::New("'Hello' + ', World!'");  
    18.   
    19.   // Compile the source code.  
    20.   Handle<Script> script = Script::Compile(source);  
    21.   
    22.   // Run the script to get the result.  
    23.   Handle<Value> result = script->Run();  
    24.   
    25.   // Dispose the persistent context.  
    26.   context.Dispose();  
    27.   
    28.   // Convert the result to an ASCII string and print it.  
    29.   String::AsciiValue ascii(result);  
    30.   printf("%s ", *ascii);  
    31.   return 0;  
    32. }  


    Handle

           在V8中,内存分配都是在V8的Heap中进行分配的,JavaScript的值和对象也都存放在V8的Heap中。这个Heap由V8独立的去维护,失去引用的对象将会被V8的GC掉并可以重新分配给其他对象。而Handle即是对Heap中对象的引用。V8为了对内存分配进行管理,GC需要对V8中的所有对象进行跟踪,而对象都是用Handle方式引用的,所以GC需要对Handle进行管理,这样GC就能知道Heap中一个对象的引用情况,当一个对象的Handle引用为发生改变的时候,GC即可对该对象进行回收(gc)或者移动。因此,V8编程中必须使用Handle去引用一个对象,而不是直接通过C++的方式去获取对象的引用,直接通过C++的方式去直接去引用一个对象,会使得该对象无法被V8管理。

           Handle分为Local和Persistent两种。从字面上就能知道,Local是局部的,它同时被HandleScope进行管理。persistent,类似与全局的,不受HandleScope的管理,其作用域可以延伸到不同的函数,而Local是局部的,作用域比较小。Persistent Handle对象需要Persistent::New, Persistent::Dispose配对使用,类似于C++中new和delete.Persistent::MakeWeak可以用来弱化一个Persistent Handle,如果一个对象的唯一引用Handle是一个Persistent,则可以使用MakeWeak方法来如果该引用,该方法可以出发GC对被引用对象的回收。

    HandleScope

    一个函数中,可以有很多Handle,而HandleScope则相当于用来装Handle(Local)的容器,当HandleScope生命周期结束的时候,Handle也将会被释放,会引起Heap中对象引用的更新。HandleScope是分配在栈上,不能通过New的方式进行创建。对于同一个作用域内可以有多个HandleScope,新的HandleScope将会覆盖上一个HandleScope,并对Local Handle进行管理。下面通过代码来讲解HandleScope的生命周期:

    1. #include <v8.h>  
    2.   
    3. using namespace v8;  
    4. int main(int argc, char* argv[]) {  
    5.   
    6.   // Create a stack-allocated handle scope.  
    7.   HandleScope handle_scope;  
    8.   // >>>>>>>>>>>>>>>>>>>>>>>>从这里开始,是HandleScope的生命周期的开始  
    9.   // 从此之后的所有Local Handle都这个handle_scope对象进行管理  
    10.   
    11.   
    12.   // Create a new context.  
    13.   Persistent<Context> context = Context::New();   //Persistent Handle  
    14.   
    15.   // Enter the created context for compiling and  
    16.   // running the hello world script.  
    17.   Context::Scope context_scope(context);  
    18.   
    19.   // Create a string containing the JavaScript source code.  
    20.   Handle<String> source = String::New("'Hello' + ', World!'"); //Local Handle  
    21.   
    22.   // Compile the source code.  
    23.   Handle<Script> script = Script::Compile(source); //Local Handle  
    24.   
    25.   // Run the script to get the result.  
    26.   Handle<Value> result = script->Run(); //Local Handle  
    27.   
    28.   // Dispose the persistent context.  
    29.   context.Dispose();  
    30.   
    31.   // Convert the result to an ASCII string and print it.  
    32.   String::AsciiValue ascii(result);  
    33.   printf("%s ", *ascii);  
    34.   return 0;  
    35.   // <<<<<<<<<<<<<<<<<<<<<<<到这里,handle_scope的生命周期结束,其析构函数将被调用,其内部的所有Local Handle将被释放  
    36. }  

    Context

    Context值得是JavaScript的执行环境。每个JavaScript都必须执行在一个Context中。Context有多个,而且可以在不同的Context中进行切换。

    1. Persistent<Context> context = Context::New();   
    2. Context::Scope context_scope(context);  

    这段代码就是申请一个Persistent contetxt,并通过Context::Scope切换到该context中。在这个Demo中,

    1. Context::Scope context_scope(context);  

    之后的所有操作都执行在context中。

    我们还可以使用

    1. Persistent<Context> context_Ex = Context::New();   
    2. Context::Scope context_scope_Ex(context_Ex);  

    来切换到context_Ex中去。

    这里只是简单的了解下Context的概念,后面将单独开辟一个章节来详细讲述V8的Context。


    从这张图可以比较清楚的看到Handle,HandleScope,以及被Handle引用的对象之间的关系。从图中可以看到,V8的对象都是存在V8的Heap中,而Handle则是对该对象的引用。

    版权申明:
    转载文章请注明原文出处,任何用于商业目的,请联系本人:hyman_tan@126.com

  • 相关阅读:
    移植nand驱动补缺:make mrproper与make clean以及make distclean,find/grep. makefile
    repo使用
    git使用总结
    notepade++使用
    linux内核源代码、配置与编译
    linux内核介绍
    块设备
    PHP和javascript中url编码解码详解
    python中的类方法、静态方法、对象方法
    webpack+vue中安装使用vue-layer弹窗插件
  • 原文地址:https://www.cnblogs.com/MingZznet/p/3231092.html
Copyright © 2011-2022 走看看