Skip to content

Instantly share code, notes, and snippets.

@tmpvar
Created April 23, 2011 14:22
Show Gist options
  • Save tmpvar/938640 to your computer and use it in GitHub Desktop.
Save tmpvar/938640 to your computer and use it in GitHub Desktop.
magic sauce to avoid jsdom memory leaks
diff --git a/src/node_script.cc b/src/node_script.cc
index ce7761d..1730671 100644
--- a/src/node_script.cc
+++ b/src/node_script.cc
@@ -57,6 +57,9 @@ class WrappedContext : ObjectWrap {
WrappedContext();
~WrappedContext();
+ void Dispose();
+
+ static Handle<Value> Stop(const Arguments& arg);
Persistent<Context> context_;
};
@@ -105,6 +108,10 @@ void WrappedContext::Initialize(Handle<Object> target) {
constructor_template->InstanceTemplate()->SetInternalFieldCount(1);
constructor_template->SetClassName(String::NewSymbol("Context"));
+ NODE_SET_PROTOTYPE_METHOD(constructor_template,
+ "stop",
+ WrappedContext::Stop);
+
target->Set(String::NewSymbol("Context"),
constructor_template->GetFunction());
}
@@ -126,9 +133,21 @@ WrappedContext::WrappedContext() : ObjectWrap() {
WrappedContext::~WrappedContext() {
- context_.Dispose();
+ this->Dispose();
}
+void WrappedContext::Dispose() {
+ if (!context_.IsEmpty()) {
+ context_.Dispose();
+ }
+}
+
+Handle<Value> WrappedContext::Stop(const Arguments& args) {
+ HandleScope scope;
+ WrappedContext *t = ObjectWrap::Unwrap<WrappedContext>(args.This());
+ t->Dispose();
+ return args.This();
+}
Local<Object> WrappedContext::NewInstance() {
Local<Object> context = constructor_template->GetFunction()->NewInstance();
var
Context = process.binding('evals').Context,
Script = process.binding('evals').Script,
total = 10000,
result = null;
process.nextTick(function memory() {
var mem = process.memoryUsage();
console.log('rss:', Math.round(((mem.rss/1024)/1024)) + "MB");
setTimeout(memory, 100);
});
console.log("STARTING");
process.nextTick(function run() {
var context = new Context(), timers = {
interval : [],
timeout : []
};
context.setInterval = function(fn, timeout) {
timers.interval.push(setInterval(fn, timeout));
},
context.setTimeout = function(fn, timeout) {
timers.timeout.push(setTimeout(fn, timeout));
};
Script.runInContext('setInterval(function() {}, 0);',
context, 'test.js');
process.nextTick(function() {
var intervalLength = timers.interval.length,
timeoutLength = timers.timeout.length;
while (intervalLength--) {
timers.interval[intervalLength].stop();
}
while (timeoutLength--) {
clearTimeout(timers.timeout[timeoutLength]);
}
context.stop();
});
total--;
if (total) {
process.nextTick(run);
} else {
console.log("COMPLETE");
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment