2011-07-14 8 views
7

私はnode.jsアドオンをC++で書いています。ネイティブインスタンスをjavascriptオブジェクトに関連付けるために、node :: ObjectWrapを使用していくつかのクラスインスタンスをラップします。私の問題は、ラップされたインスタンスのデストラクタは決して実行されないということです。ここでnode.jsネイティブアドオン - ラップされたクラスのデストラクタが実行されない

は一例です:

point.cc

#include <node.h> 
#include <v8.h> 

#include <iostream> 

using namespace v8; 
using namespace node; 

class Point 
:ObjectWrap 
{ 
protected: 
    int x; 
    int y; 
public: 
    Point(int x, int y) :x(x), y(y) { 
     std::cout << "point constructs" << std::endl; 
    } 

    ~Point() { 
     std::cout << "point destructs" << std::endl; 
    } 

    static Handle<Value> New(const Arguments &args){ 
     HandleScope scope; 

     // arg check is omitted for brevity 
     Point *point = new Point(args[0]->Int32Value(), args[1]->Int32Value()); 
     point->Wrap(args.This()); 

     return scope.Close(args.This()); 
    } 

    static void Initialize(Handle<Object> target){ 
     HandleScope scope; 

     Local<FunctionTemplate> t = FunctionTemplate::New(New); 
     t->InstanceTemplate()->SetInternalFieldCount(1); 

     NODE_SET_PROTOTYPE_METHOD(t, "get", Point::get); 

     target->Set(String::NewSymbol("Point"), t->GetFunction()); 
    } 

    static Handle<Value> get(const Arguments &args){ 
     HandleScope scope; 
     Point *p = ObjectWrap::Unwrap<Point>(args.This()); 
     Local<Object> result = Object::New(); 
     result->Set(v8::String::New("x"), v8::Integer::New(p->x)); 
     result->Set(v8::String::New("y"), v8::Integer::New(p->y)); 
     return scope.Close(result); 
    } 
}; 

extern "C" void init(Handle<Object> target) { 
    HandleScope scope; 
    Point::Initialize(target); 
}; 

test.js

var pointer = require('./build/default/point'); 

var p = new pointer.Point(1,2); 
console.log(p.get()); 

私は削除WeakPointerCallbackを、設定していると仮定しますV8のガベージコレクタが望むならば、手動で割り当てられたオブジェクト。私はどうしたらいいのですか?

+0

あなたがどのような解決策終わるのですか?あなたがオブジェクトにぶら下がってプロセス終了時に解放して手動呼び出しなしでGCを早期に防ぐのと同じように見えます。 –

+0

@NG:リソースを明示的にクリーンアップする 'close()'メソッドを提供する必要があります。 – erenon

+0

ありがとう - それは最も不幸です。 –

答えて

7

V8ではガベージコレクションが保証されていません。エンジンのメモリ不足時にのみ実行されます。残念なことに、リソースを解放する必要がある場合は、JS APIのユーザーにはあまり適していない可能性があるため、リリース機能を手動で呼び出す必要があります。 (あなたはそれが呼び出されることを確認する)(「終了」をprocess.onするためにそれを添付することができます。)

Commentary on V8

+0

リンクありがとうございます。弱いポインタと明示的なgc呼び出しでもゴミが収集されないようです(see:--expose-gc switch) – erenon

関連する問題