Добрый день.
 
Появилась интересная проблема, с которой в одиночку справится не могу и обращаюсь к вам.

Perl v.5.8.8
Операционка CentOs

Суть ПО - есть несколько миллионов предложений, программа, с помощью SynamDaemon (когда-то взятом с aot.ru) получает полную семантику предложения, далее проводит кое-какие действия и получаем "новое предложение" (авторерайтинг). В программе были замечены хаотические утечки памяти. Копание и копание и копание нашло место утечки. SynamDaemon на некоторых(редких) предложениях передает в скрипт не 1-2кб данных как обычно, а более 500кб, доходя до 30Мб. Перл выделяет память на получение данных и не освобождает её, причем выделяет довольно крупные размеры и через пару часов работы скрипта он зажирает всю память сервера.

Исходники лежат тут http://wwproject.ru/img/test.tar.gz
На код не холиварить, там все сумбурно, чтобы собрать всё в единый тест.


Я собрал порядка 500 предложений, на которые SynamDaemon неправильно реагирует и прогоняю их по этому тесту.
Сразу отмечу, что проверял много раз и память выделяется именно в момент $remote->getline()
 
Кусок кода:
sub test {
    my $sentences = Conf->base('slave')->selectall_arrayref("SELECT * FROM parse_test ORDER by id ASC", { Slice=>{} } );    
    foreach my $sentence (@$sentences) {
        print "\n--------------------\n";
        print "ID: ".$sentence->{'id'}."  ";
        my $ret_rules = get_socket_data($sentence->{'data_text'});
        print "\n Memory: ".get_memory();
    }    
}

sub get_socket_data {
    my $sentence = shift;
    
    $sentence = utf_to_cp1251(pack 'C*', unpack 'U0C*', $sentence);
    
    my $lang = "_Russian";
    my $str = $lang."#".utf_to_cp1251($sentence);
    my $strLen = length($str);
    
    my $req = pack("V", $strLen).$lang."#".$sentence;
    
    my @data="" />    
    my $remote = IO::Socket::INET->new(
        'Proto'    => 'tcp',
        'Timeout'  => 3,
        'PeerAddr' => 'localhost',
        'PeerPort' => 9090
    );

    if ($remote) {
        print $remote $req;
        #push @data,$remote->getlines();        
        
        my $i=0;
        while ( my $line = $remote->getline ) {
            push @data,$line;
            $i++;
        }
        #warn "Lines: ".$i; # вот тут оказалось, что все идет в 1 строку
        close $remote;
    }

    my $result = pack 'U0C*', unpack 'C*', cp1251_to_utf(join('',@data));
    
    print "Get Length: ".(length $result);
    
    return $result;
}


Кусок кода из логов:
--------------------
ID: 1  Get Length: 1157940
 Memory: 124506112
--------------------
ID: 2  Get Length: 1730569
 Memory: 169852928
--------------------
ID: 3  Get Length: 3447876
 Memory: 280252416
--------------------
ID: 4  Get Length: 1009747
 Memory: 272359424
--------------------
ID: 5  Get Length: 1085522
 Memory: 272359424
--------------------
ID: 6  Get Length: 3535001
 Memory: 296792064
--------------------
ID: 7  Get Length: 2091008
 Memory: 292573184
--------------------
ID: 8  Get Length: 2776465
 Memory: 301273088
--------------------
ID: 9  Get Length: 5706835
 Memory: 445558784
--------------------
ID: 10  Get Length: 6386430
 Memory: 561889280
--------------------
ID: 11  Get Length: 2291249
 Memory: 522055680
--------------------


--------------------
ID: 212  Get Length: 1769513
 Memory: 731144192
--------------------
ID: 213  Get Length: 550348
 Memory: 731144192
--------------------
ID: 214  Get Length: 541876
 Memory: 703389696
--------------------
ID: 215  Get Length: 17032988
 Memory: 1192304640
--------------------
ID: 216  Get Length: 4204764
 Memory: 1158500352
--------------------
ID: 217  Get Length: 1631550
 Memory: 1158500352
--------------------


--------------------
ID: 251  Get Length: 724272
 Memory: 1110773760
--------------------
ID: 252  Get Length: 2905076
 Memory: 1126662144
--------------------
ID: 253  Get Length: 1179906
 Memory: 1126662144
--------------------
ID: 254  Get Length: 26327835
 Memory: 1879842816
--------------------
ID: 255  Get Length: 2612506
 Memory: 1762312192
--------------------
ID: 256  Get Length: 1997323
 Memory: 1762312192
--------------------

--------------------

Главный вопрос тут, почему память не освобождается? И какие есть возможные пути решения?

 
 
 
 
--
С Уважением, Login|off Nick или STork.
-- 
Moscow.pm mailing list
[email protected] | http://moscow.pm.org

Ответить