I'm having some surprising results in my Nodetime heap snapshot:
Am I reading this right that there are 1706 instances of a "user" in my heap? This seems absurdly high, I'm not even quite sure how I would have allocated that many. In any case, are there any tips / tricks / hints to find out why these are hanging around? I've already used JSHint on my code to ensure there are no free globals being allocated. Everything should be wrapped in the closure scope of the request... so why aren't the users, posts, etc. being garbage collected when the request finishes? Here's some (redacted) code to show how I'm doing things...
What's very surprising is that I took the above heap snapshot about 10m after the last API call finished. So, those objects were all hanging around for long after the requests which triggered them to be allocated was finished!
code:
var User = require('./user').User,
Q = require('q');
// this function is called via express' router, eg when the client visits myapi.com/users/zane
function getUser(req, res, next)
{
var user = extend({},User).initialize();
Q.ncall(user.model.find, user.model, {'username': req.arguments[0]})
.then(function(data){
res.writeHead(200, {});
res.end(JSON.stringify(data));
})
.fail(next).end();
}
And the "User" module looks something like this:
exports.User = extend({}, {
initialize: function() {
var Schema = api.mongoose.Schema;
this.schema = new Schema({
'username': {'type':String, 'index':true}
});
this.model = api.db.model('users', this.schema);
}
// ... some other helper functions in here
});
Based upon my express code, above, I'd expect the lifespan of the user object which is allocated to be only as long as the request takes to return. Am I missing some key Node.js GC idea here?
This line looks suspiciously inefficient:
var user = extend({},User).initialize();
I'm assuming the extend
call copies the User
object and then calls its initialize
method. Why are you copying the User
object on each API invocation?
Then in the initialize
call you create a new Mongoose schema object and then register it as a model via the api.db.model
call. Wouldn't it be better to create the schema once and register it during initialization?
The combination of both of these may be resulting in more objects being created on each call than necessary, and I bet those registered Mongoose models do not GC easily.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With