1

I have app build with restify.js and I detected memory leak. I am lucky because memory leak is "heavy" and I can reproduce it easily. It behaves the same on my local Mac and on Heroku where app is hosted. As a proove here are memory usage statistics from Librato addon on Heroku:

Dyno memory usage

Memory usage goes up when I am doing requests :). Unfortunately I cant track where exactly memory leaks... It happens for all routes/endpoints, however memory is growing faster when request takes more time to finish... Anyway I can use restify.js dtrace probes, but only to get middleware/handler latency. I am using following DTRACE script:

#!/usr/sbin/dtrace -s
#pragma D option quiet

restify*:::route-start
{
   track[arg2] = timestamp;
}

restify*:::handler-start
/track[arg3]/
{
   h[arg3, copyinstr(arg2)] = timestamp;
}

restify*:::handler-done
/track[arg3] && h[arg3, copyinstr(arg2)]/
{
   @[copyinstr(arg2)] = quantize((timestamp - h[arg3, copyinstr(arg2)]) / 1000000);
   h[arg3, copyinstr(arg2)] = 0;
}

restify*:::route-done
/track[arg2]/
{
   @[copyinstr(arg1)] = quantize((timestamp - track[arg2]) / 1000000);
   track[arg2] = 0;
} 

And output for the script is for example:

 handler-4                                         
           value  ------------- Distribution ------------- count    
              -1 |                                         0        
               0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 7        
               1 |                                         0        

  pre_apiVersion                                    
           value  ------------- Distribution ------------- count    
              -1 |                                         0        
               0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 7        
               1 |                                         0        

  pre_authenticate                                  
           value  ------------- Distribution ------------- count    
              -1 |                                         0        
               0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 7        
               1 |                                         0        

  pre_restifyCors                                   
           value  ------------- Distribution ------------- count    
              -1 |                                         0        
               0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 7        
               1 |                                         0        

  pre_restifyFullResponse                           
           value  ------------- Distribution ------------- count    
              -1 |                                         0        
               0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 7        
               1 |                                         0        

  use_authorize                                     
           value  ------------- Distribution ------------- count    
              -1 |                                         0        
               0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 7        
               1 |                                         0        

  use_errors                                        
           value  ------------- Distribution ------------- count    
              -1 |                                         0        
               0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 7        
               1 |                                         0        

  use_language                                      
           value  ------------- Distribution ------------- count    
              -1 |                                         0        
               0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 7        
               1 |                                         0        

  use_modules                                       
           value  ------------- Distribution ------------- count    
              -1 |                                         0        
               0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 7        
               1 |                                         0        

  use_restifyBodyParserParseBody                    
           value  ------------- Distribution ------------- count    
              -1 |                                         0        
               0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 7        
               1 |                                         0        

  use_restifyBodyParserReadBody                     
           value  ------------- Distribution ------------- count    
              -1 |                                         0        
               0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 7        
               1 |                                         0        

  use_restifyQueryParser                            
           value  ------------- Distribution ------------- count    
              -1 |                                         0        
               0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 7        
               1 |                                         0        

  use_restifyRequestLogger                          
           value  ------------- Distribution ------------- count    
              -1 |                                         0        
               0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 7        
               1 |                                         0        

  use_validate                                      
           value  ------------- Distribution ------------- count    
              -1 |                                         0        
               0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 7        
               1 |                                         0        

  pre                                               
           value  ------------- Distribution ------------- count    
              -1 |                                         0        
               0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@       6        
               1 |@@@@@@                                   1        
               2 |                                         0        

  use_restifyGzipResponse                           
           value  ------------- Distribution ------------- count    
               0 |                                         0        
               1 |@@@@@@                                   1        
               2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@       6        
               4 |                                         0        

  handler                                           
           value  ------------- Distribution ------------- count    
              16 |                                         0        
              32 |@@@@@@@@@@@                              2        
              64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@            5        
             128 |                                         0        

  route_module_list001                              
           value  ------------- Distribution ------------- count    
              16 |                                         0        
              32 |@@@@@@@@@@@                              2        
              64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@            5        
             128 |                                         0  

My questions are:

  1. Is there any option to write this DTRACE script to not count latency, but to count memory usage differences? Then I could check every middleware how much memory it allocates? Hmm, I guess javascript in V8 allocates memory in batches only when needed, am I right?

  2. Maybe you have any other ideas how to investigate this memory leak? I tried to comment some of the middlewares and so on but still cant find source of the problem :(.


EDIT: here is comparison of two heap snapshots - first one is done after 1 requests and second after next 100 requests. Can any one tell me what does it mean?:

Heap comparison between 100 requests

user606521
  • 14,486
  • 30
  • 113
  • 204
  • The fact that dyno memory increase does not necessarily mean you have a leak. Before going into further detail: are you actually seeing out-of-memory errors? – Nitzan Shaked Jul 21 '14 at 23:29
  • Yes, yesterday I had "Dyno out of memory" errors and I had to restart app. I tried to analyze heapsnapshots, hoverver I cant figure out whats happening. For sure number of (arrays) and (Objects) is increasing... – user606521 Jul 22 '14 at 07:03
  • Will you see the same increase in heap objects if you capture one more heap snapshot, after 100 more requests? If so, then you probably *do* have a leak. Try posting your code? – Nitzan Shaked Jul 22 '14 at 17:40
  • Yup I do have a leak. Can't paste code here - its too much code. I am investigating by commenting out some parts of it and running load tests. – user606521 Jul 22 '14 at 18:51
  • @user606521How did it went back then? Found the cause? We're experiencing very similar. – Vasyl Boroviak Apr 29 '15 at 00:20
  • 1
    @VasiliyBorovyak After few weeks of investigation I found the cause - it was probably pg-native module. I am using Sequelize.js to connect to pg database - when I was using native: true flag then I memory was growing constantly - when switched to native: false memory started to behave normally. – user606521 Apr 30 '15 at 11:14

0 Answers0