Permalink
Browse files

Fix Memory Leak

  • Loading branch information...
1 parent fd28aa1 commit 03ceca8ebbc22fd896d72c6d085dade49fce4443 @groundwater groundwater committed Oct 18, 2012
Showing with 84 additions and 32 deletions.
  1. +2 −2 example.js
  2. +82 −30 src/gc.cc
View
@@ -1,7 +1,7 @@
var b = require("./index")
-b.onGC(function(x){
- console.log("Heap After GC: ",x);
+b.onGC(function(usage,type,flags,type_raw,flags_raw){
+ console.log("Heap After GC: ",usage,type,flags,type_raw,flags_raw);
});
var l=[];
View
112 src/gc.cc
@@ -8,22 +8,34 @@ using namespace node;
Persistent<Function> afore_callback;
Persistent<Object> afore_context;
-struct ReshelveBaton {
+struct Baton {
+
// Required //
uv_work_t request;
// Use Defined [Optional] //
- size_t heap_size;
+
+ size_t * stats; // The HeapStatistics Snapshot
+ GCType gcType;
+ GCCallbackFlags gcFlags;
+
};
-static size_t getheap() {
+static size_t* getheap() {
+
+ HeapStatistics heap;
+
+ V8::GetHeapStatistics(&heap);
+
+ size_t * stats = new size_t[4];
+
+ stats[0] = heap.used_heap_size();
+ stats[1] = heap.total_heap_size();
+ stats[2] = heap.heap_size_limit();
+ stats[3] = heap.total_heap_size_executable();
+
+ return stats;
- HeapStatistics stats;
-
- V8::GetHeapStatistics(&stats);
-
- return stats.used_heap_size();
-
}
static void nothing(uv_work_t* request)
@@ -35,14 +47,49 @@ static void nothing(uv_work_t* request)
// Executed on a the main even loop / thread
static void after_gc_async(uv_work_t* request)
{
-
- ReshelveBaton *baton = static_cast<ReshelveBaton*>(request->data);
-
- Handle<Value> argv[1];
- argv[0] = Integer::New(baton->heap_size);
-
- afore_callback->Call(afore_context,1, argv);
-
+
+ Baton *baton = static_cast<Baton*>(request->data);
+
+ Handle<Value> argv[5];
+ argv[0] = Integer::New(baton->stats[0]);
+
+ switch(baton->gcType)
+ {
+ case kGCTypeAll:
+ argv[1] = String::New("kGCTypeAll");
+ break;
+ case kGCTypeMarkSweepCompact:
+ argv[1] = String::New("kGCTypeMarkSweepCompact");
+ break;
+ case kGCTypeScavenge:
+ argv[1] = String::New("kGCTypeScavenge");
+ break;
+ default:
+ argv[1] = String::New("UnknownType");
+ break;
+ }
+
+ switch(baton->gcFlags)
+ {
+ case kGCCallbackFlagCompacted:
+ argv[2] = String::New("kGCCallbackFlagCompacted");
+ break;
+ case kNoGCCallbackFlags:
+ argv[2] = String::New("kNoGCCallbackFlags");
+ break;
+ default:
+ argv[2] = String::New("UnknownFlags");
+ break;
+ }
+
+ argv[3] = Integer::New(baton->gcType);
+ argv[4] = Integer::New(baton->gcFlags);
+
+ afore_callback->Call(afore_context,5, argv);
+
+ delete [] baton->stats;
+ delete baton;
+
}
// Callback executed on whatever thread the GC runs
@@ -51,42 +98,47 @@ static void after_gc_async(uv_work_t* request)
static void after_gc(GCType type, GCCallbackFlags flags)
{
- ReshelveBaton *baton = new ReshelveBaton();
+ Baton *baton = new Baton();
baton->request.data = baton;
-
- baton->heap_size = getheap();
-
+
+ baton->stats = getheap();
+
+ baton->gcType = type;
+ baton->gcFlags = flags;
+
uv_queue_work(uv_default_loop(), &baton->request, nothing, after_gc_async);
}
+// Handle<Value> qualifies as a V8 Function
static Handle<Value> RegisterCallback(const Arguments& args) {
-
- Handle<Function> cb = Handle<Function>::Cast(args[0]);
- Handle<BooleanObject> handleAll = Handle<BooleanObject>::Cast(args[1]);
- GCType type = kGCTypeMarkSweepCompact;
+ Handle<Function> cb = Handle<Function>::Cast(args[0]);
// We retain these as Persistent objects for async callbacks
afore_callback = Persistent<Function>::New(cb);
afore_context = Persistent<Object>::New(Context::GetCalling()->Global());
-
+
// Receive a callback _only_ after a full GC of
// type kGCTypeMarkSweepCompact
//
// this callback executes on a separate thread
- V8::AddGCEpilogueCallback(after_gc,type);
-
+ V8::AddGCEpilogueCallback(after_gc);
// The function must return, even if it's nothing
return Undefined();
+
}
+// Setup the module
static void init(Handle<Object> target) {
-
+
+ // target is like module.exports
+ // we are assigning the function 'onGC'
+ // to the module
target->Set(String::NewSymbol("onGC"),
FunctionTemplate::New(RegisterCallback)->GetFunction());
-
+
}
NODE_MODULE(gcinfo, init)

0 comments on commit 03ceca8

Please sign in to comment.