Добрый день.
Появилась интересная проблема, с которой в одиночку справится не могу и обращаюсь к вам.
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()
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
--------------------
--------------------
Главный вопрос тут, почему память не освобождается? И какие есть возможные пути решения?
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.
С Уважением, Login|off Nick или STork.
-- Moscow.pm mailing list [email protected] | http://moscow.pm.org
