Утечка памяти в приложении узла - как исследовать на Mac OS X?

У меня есть приложение с билдом restify.js и я обнаружил утечку памяти. Мне повезло, потому что утечка памяти "тяжелая", и я могу легко ее воспроизвести. Он ведет себя одинаково на моем локальном Mac и на Heroku, где размещено приложение. В качестве доказательства приведем статистику использования памяти из дополнения Librato на Heroku:

Использование памяти Dyno

Использование памяти увеличивается, когда я делаю запросы:). К сожалению, я не могу отследить, где именно происходит утечка памяти... Это происходит для всех маршрутов / конечных точек, однако память растет быстрее, когда запрос занимает больше времени для завершения... В любом случае я могу использовать пробники restify.js dtrace, но только для получения промежуточного программного обеспечения / задержка обработчика. Я использую следующий скрипт DTRACE:

#!/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;
} 

И вывод для скрипта, например:

 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  

Мои вопросы:

  1. Есть ли возможность написать этот сценарий DTRACE, чтобы не считать задержки, а считать разницу в использовании памяти? Тогда я мог бы проверить каждое промежуточное ПО, сколько памяти он выделяет? Хм, я думаю, Javascript в V8 выделяет память в пакетах только при необходимости, я прав?

  2. Может быть, у вас есть другие идеи, как исследовать эту утечку памяти? Я попытался прокомментировать некоторые промежуточные программы и так далее, но все еще не могу найти источник проблемы:(.


РЕДАКТИРОВАТЬ: здесь сравниваются два снимка кучи - первый выполняется после 1 запроса, а второй после 100 запросов. Кто-нибудь может сказать мне, что это значит?

Сравнение кучи между 100 запросами

0 ответов

Другие вопросы по тегам