[Rt-devel] Memory 'leak' in Ticket/Display.html

Bram rtdevel at lists.wizbit.be
Thu Jul 23 06:00:29 EDT 2009


Hi,


When a large search is done and the user clicks the link to display  
the ticket then apache starts using a lot more memory.
This is due to a memory 'leak' in share/html/Ticket/Display.html:

http://github.com/bestpractical/rt/blob/90546414c8887e344f995da5f20f53a58939bbd8/share/html/Ticket/Display.html
lines 200-206:

if (defined $session{'tickets'} and ($ARGS{'Query'} or  
$session{'CurrentSearchHash'}->{'Query'})) {
     my $item_map = $session{'tickets'}->ItemMap;
     $link_rel{first} = "Ticket/Display.html?id=" . $item_map->{first}  
                if $item_map->{$TicketObj->Id}{prev};
     $link_rel{prev}  = "Ticket/Display.html?id=" .  
$item_map->{$TicketObj->Id}{prev} if $item_map->{$TicketObj->Id}{prev};
     $link_rel{next}  = "Ticket/Display.html?id=" .  
$item_map->{$TicketObj->Id}{next} if $item_map->{$TicketObj->Id}{next};
     $link_rel{last}  = "Ticket/Display.html?id=" . $item_map->{last}   
                if $item_map->{$TicketObj->Id}{next};
}


This code will execute the query in $session{'tickets'} and store the  
results of the search in $session{'tickets'}->....
Meaning: the session object now contains the query + the results of  
the search. Which obviously results in a lot higher memory usage when  
the search is large.

(When I run a search which returns 13000 tickets apache jumps from  
40/60 mb of memory to 200mb of memory.
Since it is in the session it also means every later request from the  
same session will result in another process using 200mb of memory.)


I modified the code a bit and added Dumper($session{tickets});
I then did a search for 2 tickets. (truncated Dumper output at the end).

A (truncated) diff from the dumper output:

(- is before, + is after)
-                 'must_redo_search' => 1,
+                 'must_redo_search' => 0,

+                 'items_array' => [],

+                 'dbix_sb_unique_cache' => {
+                                             '37737' => 1,
+                                             '39447' => 1
+                                           },

+                 'item_map' => {
+                                 '37737' => {
+                                            'next' => '39447',
+                                            'prev' => 0,
+                                            'defined' => 1
+                                          },
+                                 'first' => '37737',
+                                 '39447' => {
+                                              'prev' => '37737',
+                                              'defined' => 1
+                                            },
+                                 'last' => '39447'
+                               },

+                 'items' => [
+                              bless( {
+                                       '_Class' => 'RT::Ticket',
+                                       'original_user' => undef,
+                                        
'_SB_Record_Primary_RecordCache_key' => 'id=37737',
+                                       'user' => $VAR1->{'user'},
+                                       'table' => 'Tickets',
+                                       'values' => {
+                                                      # [snipped]
+                                                   },
+                                       'fetched' => {
+                                                      # [snipped]
+                                                    }
+                                     }, 'RT::Ticket' ),
+                              bless( {
+                                       '_Class' => 'RT::Ticket',
+                                       'original_user' => undef,
+                                        
'_SB_Record_Primary_RecordCache_key' => 'id=39447',
+                                       'user' => $VAR1->{'user'},
+                                       'table' => 'Tickets',
+                                       'values' => {
+                                                      # [snipped]
+                                                   },
+                                       'fetched' => {
+                                                      # [snipped]
+                                     }, 'RT::Ticket' )
+                            ]


This means that after the display it contains extra data in items,  
item_map and dbix_sb_unique_cache.
Clearing items is simple and can be done by adding:
     $session{'tickets'}->PrepForSerialization();

in the code (which is what Search/Results.html calls).


But that still leaves item_map and dbix_sb_unique_cache in the session.
Any advice on clearing those?


Best regards,

Bram



(Truncated) Dumper output:

[Thu Jul 23 12:49:59 2009] [info]: BEFORE  
(/opt/rt3/local/html/Ticket/Display.html:223)
[Thu Jul 23 12:49:59 2009] [info]: $VAR1 = bless( {
                  '_open_parens' => {},
                  'alias_count' => 0,
                  'table' => 'Tickets',
                  'where_clause' => '',
                  'order_by' => [
                                  {
                                    'FIELD' => 'id',
                                    'ORDER' => 'ASC'
                                  }
                                ],
                  'RecalcTicketLimits' => 0,
                  '_sql_trattachalias' => undef,
                  '_sql_object_cfv_alias' => undef,
                  'is_limited' => 1,
                  'order' => '',
                  '_sql_watcher_join_users_alias' => undef,
                  'user' => bless( {
                                     # [ snipped ]
                                   }, 'RT::CurrentUser' ),
                  'restriction_index' => 1,
                  '_sql_query' => 'id = 37737 OR id = 39447',
                  '_sql_transalias' => undef,
                  'DBIxHandle' => bless( {
                                           'dsn' =>  
'dbi:Pg:dbname=ayuda;host=db',
                                           'StatementLog' => [],
                                           'DisconnectHandleOnDestroy' => undef
                                         }, 'RT::Handle' ),
                  'limit_clause' => '',
                  'restrictions' => {
                                      'main.Status' => [
                                                         {
                                                           'value' =>  
'\'deleted\'',
                                                           'field' =>  
'main.Status',
                                                           'op' => '!='
                                                         }
                                                       ],
                                      'ticketsql' => [
                                                       {
                                                         'value' =>  
'\'37737\'',
                                                         'field' => 'main.id',
                                                         'op' => '='
                                                       },
                                                       'OR',
                                                       {
                                                         'value' =>  
'\'39447\'',
                                                         'field' => 'main.id',
                                                         'op' => '='
                                                       }
                                                     ],
                                      'main.EffectiveId' => [
                                                              {
                                                                 
'value' => 'main.id',
                                                                 
'field' => 'main.EffectiveId',
                                                                'op' => '='
                                                              }
                                                            ],
                                      'main.Type' => [
                                                       {
                                                         'value' =>  
'\'ticket\'',
                                                         'field' =>  
'main.Type',
                                                         'op' => '='
                                                       }
                                                     ]
                                    },
                  'primary_key' => 'id',
                  'count_all' => '2',
                  'must_redo_search' => 1,
                  'looking_at_effective_id' => 0,
                  'itemscount' => 0,
                  'show_rows' => 0,
                  '_sql_cf_alias' => undef,
                  'left_joins' => {},
                  'aliases' => [],
                  'subclauses' => {
                                    'generic_restrictions' =>  
'(main.Status != \'deleted\') AND (main.id = \'37737\' OR main.id =  
\'39447\') AND (main.Type = \'ticket\') AND (main.EffectiveId =  
main.id)'
                                  },
                  'first_row' => 0,
                  'looking_at_type' => 0,
                  '_sql_looking_at' => {
                                         'id' => 1
                                       }
                }, 'RT::Tickets' );  
(/opt/rt3/local/html/Ticket/Display.html:224)


[Thu Jul 23 12:50:00 2009] [info]: AFTER  
(/opt/rt3/local/html/Ticket/Display.html:233)
[Thu Jul 23 12:50:00 2009] [info]: $VAR1 = bless( {
                  '_open_parens' => {},
                  'table' => 'Tickets',
                  '_sql_trattachalias' => undef,
                  '_sql_object_cfv_alias' => undef,
                  'is_limited' => 1,
                  'order' => '',
                  '_sql_watcher_join_users_alias' => undef,
                  'user' => bless( {
                                     # [ snipped ]
                                   }, 'RT::CurrentUser' ),
                  '_sql_query' => 'id = 37737 OR id = 39447',
                  'restrictions' => {
                                      'main.Status' => [
                                                         {
                                                           'value' =>  
'\'deleted\'',
                                                           'field' =>  
'main.Status',
                                                           'op' => '!='
                                                         }
                                                       ],
                                      'ticketsql' => [
                                                       {
                                                         'value' =>  
'\'37737\'',
                                                         'field' => 'main.id',
                                                         'op' => '='
                                                       },
                                                       'OR',
                                                       {
                                                         'value' =>  
'\'39447\'',
                                                         'field' => 'main.id',
                                                         'op' => '='
                                                       }
                                                     ],
                                      'main.EffectiveId' => [
                                                              {
                                                                 
'value' => 'main.id',
                                                                 
'field' => 'main.EffectiveId',
                                                                'op' => '='
                                                              }
                                                            ],
                                      'main.Type' => [
                                                       {
                                                         'value' =>  
'\'ticket\'',
                                                         'field' =>  
'main.Type',
                                                         'op' => '='
                                                       }
                                                     ]
                                    },
                  'primary_key' => 'id',
                  'count_all' => '2',
                  'items_array' => [],
                  'must_redo_search' => 0,
                  'looking_at_effective_id' => 0,
                  'subclauses' => {
                                    'generic_restrictions' =>  
'(main.Status != \'deleted\') AND (main.id = \'37737\' OR main.id =  
\'39447\') AND (main.EffectiveId = main.id) AND (main.Type =  
\'ticket\')'
                                  },
                  '_sql_looking_at' => {
                                         'id' => 1
                                       },
                  'alias_count' => 0,
                  'dbix_sb_unique_cache' => {
                                              '37737' => 1,
                                              '39447' => 1
                                            },
                  'order_by' => [
                                  {
                                    'FIELD' => 'id',
                                    'ORDER' => 'ASC'
                                  }
                                ],
                  'where_clause' => '',
                  'RecalcTicketLimits' => 0,
                  '_sql_transalias' => undef,
                  'restriction_index' => 1,
                  'item_map' => {
                                  '37737' => {
                                             'next' => '39447',
                                             'prev' => 0,
                                             'defined' => 1
                                           },
                                  'first' => '37737',
                                  '39447' => {
                                               'prev' => '37737',
                                               'defined' => 1
                                             },
                                  'last' => '39447'
                                },
                  'limit_clause' => '',
                  'DBIxHandle' => bless( {
                                           'dsn' =>  
'dbi:Pg:dbname=ayuda;host=db',
                                           'StatementLog' => [],
                                           'DisconnectHandleOnDestroy' => undef
                                         }, 'RT::Handle' ),
                  'itemscount' => 0,
                  '_sql_cf_alias' => undef,
                  'show_rows' => 0,
                  'left_joins' => {},
                  'aliases' => [],
                  'first_row' => 0,
                  'looking_at_type' => 0,
                  'items' => [
                               bless( {
                                        '_Class' => 'RT::Ticket',
                                        'original_user' => undef,
                                         
'_SB_Record_Primary_RecordCache_key' => 'id=37737',
                                        'user' => $VAR1->{'user'},
                                        'table' => 'Tickets',
                                        'values' => {
                                                      # [snipped]
                                                    },
                                        'fetched' => {
                                                      # [snipped]
                                                     }
                                      }, 'RT::Ticket' ),
                               bless( {
                                        '_Class' => 'RT::Ticket',
                                        'original_user' => undef,
                                         
'_SB_Record_Primary_RecordCache_key' => 'id=39447',
                                        'user' => $VAR1->{'user'},
                                        'table' => 'Tickets',
                                        'values' => {
                                                      # [snipped]
                                                    },
                                        'fetched' => {
                                                      # [snipped]
                                                     }
                                      }, 'RT::Ticket' )
                             ]
                }, 'RT::Tickets' );  
(/opt/rt3/local/html/Ticket/Display.html:234)





More information about the Rt-devel mailing list