-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
Closed
Labels
c++Issues and PRs that require attention from people who are familiar with C++.Issues and PRs that require attention from people who are familiar with C++.memoryIssues and PRs related to the memory management or memory footprint.Issues and PRs related to the memory management or memory footprint.questionIssues that look for answers.Issues that look for answers.
Description
First I'm sorry for my english is not good.
I detect memory leak during aging test developed source.
I guess that occurred by node js.
My real source is can't upload because it is violate my company's security policy.
So I tested by modified node js test source(https://github.com/nodejs/node/tree/master/test/addons/async-hello-world).
Modified source is below.
- binding.cc
#include <node.h>
#include <v8.h>
#include <uv.h>
struct async_req {
uv_work_t req;
int input;
int output;
v8::Isolate* isolate;
v8::Persistent<v8::Function> callback;
};
void DoAsync(uv_work_t* r) {
async_req* req = reinterpret_cast<async_req*>(r->data);
//Sleep(1000); // Simulate CPU intensive process...
req->output = req->input * 2;
}
void AfterAsync(uv_work_t* r) {
async_req* req = reinterpret_cast<async_req*>(r->data);
v8::Isolate* isolate = req->isolate;
v8::HandleScope scope(isolate);
v8::Local<v8::Value> argv[2] = {
v8::Null(isolate),
v8::Integer::New(isolate, req->output)
};
v8::TryCatch try_catch(isolate);
v8::Local<v8::Function> callback =
v8::Local<v8::Function>::New(isolate, req->callback);
callback->Call(isolate->GetCurrentContext()->Global(), 2, argv);
// cleanup
req->callback.Reset();
delete req;
if (try_catch.HasCaught()) {
node::FatalException(isolate, try_catch);
}
}
void Method(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate();
v8::HandleScope scope(isolate);
async_req* req = new async_req;
req->req.data = req;
req->input = args[0]->IntegerValue();
req->output = 0;
req->isolate = isolate;
v8::Local<v8::Function> callback = v8::Local<v8::Function>::Cast(args[1]);
req->callback.Reset(isolate, callback);
uv_queue_work(uv_default_loop(),
&req->req,
DoAsync,
(uv_after_work_cb)AfterAsync);
}
void init(v8::Local<v8::Object> exports, v8::Local<v8::Object> module) {
NODE_SET_METHOD(module, "exports", Method);
}
NODE_MODULE(binding, init);
- binding.gyp
{
'targets': [
{
'target_name': 'binding',
'sources': [ 'binding.cc' ]
}
]
}
- test.js
'use strict';
var assert = require('assert');
var binding = require('./build/Release/binding');
invoke(0);
function invoke(cnt) {
if (cnt < 100000) {
binding(5, function(err, val) {
global.gc();
if (cnt % 100 === 0) {
console.log(cnt / 100, process.memoryUsage().heapUsed);
}
process.nextTick(function() {
invoke(++cnt);
});
});
}
I run repeat 100,000 times binding addon, every time run gc and print memory usage when each 100th times.
Memory usage result is below.
I test on Windows 7 64bit, Node v.4.2.1. Node-gyp v.3.0.3.
Is it really memory leak? or do I use nodejs incorrectly?
Metadata
Metadata
Assignees
Labels
c++Issues and PRs that require attention from people who are familiar with C++.Issues and PRs that require attention from people who are familiar with C++.memoryIssues and PRs related to the memory management or memory footprint.Issues and PRs related to the memory management or memory footprint.questionIssues that look for answers.Issues that look for answers.