Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tracking memory usage? #242

Closed
dcsan opened this issue Aug 10, 2017 · 2 comments
Closed

tracking memory usage? #242

dcsan opened this issue Aug 10, 2017 · 2 comments
Labels

Comments

@dcsan
Copy link
Contributor

dcsan commented Aug 10, 2017

we have a node app that's using a ton of memory, and i'm wondering with rivescript how best to track this kind of usage?

within the rive object, how can I see how many users are being tracked, and how many user variables there are? since this seems to vary with users over time.

I was looking through the brain file
https://github.com/aichaos/rivescript-js/blob/master/src/brain.coffee

rivescript creates a new brain passing in an instance of the rivescript obj:

...coffeescript
// in rivescript class
    @brain  = new Brain @

class Brain
  constructor: (master) ->

so just one brain instance, not per user?

is rivescript._users the main place to look for uservars and any ballooning list of objects?

@kirsle
Copy link
Member

kirsle commented Aug 10, 2017

so just one brain instance, not per user?

Right. So when you initialize a new RiveScript(), that instance creates a handful of "singleton" helper classes from Brain, Parser and such. So that these helpers can get access to the parent RiveScript instance, it passes itself into their constructors as you saw. This all should be fine and not memory-leaky, barring the discovery of another crazy JavaScript quirk.

The first place I'd check for memory usage is rivescript._users because that could grow without bound depending how many users have chatted with the bot. When we get async/await from #220 we'll be able to use external databases/caches for user variables which should help a lot here.

When I was benchmarking Alice at https://github.com/aichaos/alice-benchmarks, I saw a memory leak when trying to completely destroy the entire RiveScript object and build a new one from scratch. If your use case involves doing anything similar, that might be part of the problem too. My guess is that JavaScript doesn't garbage collect large data structures that are self-referential -- Perl has the same problem as I found one day. So for example, the rivescript._sorted structure has pointers to all the trigger data from rivescript._topics, so if you tried to just do rivescript = null;, those self-referential pointers don't get cleaned up properly. (It might be nice to add a .destroy() function that loops through and breaks all the references to clean up the RiveScript object more efficiently)

@kirsle kirsle added the question label Mar 4, 2018
@kirsle kirsle closed this as completed Mar 4, 2018
@kirsle
Copy link
Member

kirsle commented Mar 4, 2018

More recently I learned that Node/v8's garbage collection algorithm is of the mark-and-sweep variety (like in Go), not by counting references (as in Python or Perl). So when you uninitialize an object that has self-references inside it, the v8 engine should identify that those variables are unreachable by any current code anymore, and eventually clean it up without letting it leak forever.

However, I've also seen recently that Node will delay collecting garbage until it absolutely has to, so it might leak memory for a while before it finally stops the world and does some spring cleaning.

If you keep one RiveScript instance for the lifetime of your app and don't delete and reinitialize it constantly, it should be fine. It has self-references in the form of its helper classes referring back to the parent, but there's a limited number of such references and they don't grow over time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants