一个关于perl out of memory的问题

wish4sun 2011-03-08 10:14:55
我写了一个导数据用的perl程序,运行的时候刚开始还可以,然后到了某一条数据突然就不再继续运行了,然后我查看内存占用情况,就会一直增长,一直耗光内存,然后提示out of memory
,如果是我的其中一个变量持续增长应该是改程序占用内存也是持续增长的,可是我观察内存占用情况,刚开始该程序一直维持在一个很低的情况,直到遇到某一条数据后,就开始一直增长了,请各位大侠们帮帮我,我死活找不出原因,我是perl新手,不太会debug。谢谢各位了。

下面是源代码,处于公司保密目的,我将其中的接口和数据库IP给替换成xxxxxx了,请各位多包涵!

#!/usr/bin/perl -w
use strict;
use warnings;
use DBI;
use XML::Smart;
use Data::Dumper;
use Encode qw/encode decode/;
use Digest::MD5 qw(md5 md5_hex md5_base64);
use MIME::Base64 qw(encode_base64 decode_base64);
use LWP::UserAgent;
require "db.pl";
my $dbh = &get_joy_db;
#my $ii = 0;
#my $jj = 0;
my %db_joyid;

my %all_urls = ("电视剧"=>"http://xxxxx/get_list.php?channelid=58",
"电影"=>"http://xxxxx/get_list.php?channelid=51",
"播客"=>"http://xxxxx/get_video_list.php?channelid=1",
"娱乐"=>"http://xxxxx/get_video_list.php?channelid=3");


while(my ($cat, $url) = each %all_urls){
my @content_url = return_url_update($url);
foreach my $u (@content_url) {
print $cat,$u."\n";
my $XML = XML::Smart->new( $u, 'XML::Smart::Parser' );
my @items = reverse(@{ $XML->{root}{videolist}{video}});
foreach my $item (@items) {
print "\n\n\n";
my $title = $dbh->quote(&encode("GBK",$item->{title}));
#print $title."\n";
my $id = &encode("GBK",$item->{id});
my $intro = $dbh->quote(&encode("GBK",$item->{desc}));
my $tags = $dbh->quote(&encode("GBK",$item->{tag}));
my $play_url = &encode("GBK",$item->{play_url});
my $src_image = &encode("GBK",$item->{img_url});
my $time = &encode("GBK",$item->{totaltime});
my $image = handleJoyPic($src_image,"joy");
$image = "http://cnimg.realnetworks.com.cn/guide/mdb/".$image;
my ($curdate,$curtime)=get_time();
print $cat."===>".$title."=>".$id."=>".$image."\n";
my $sql_chk = "select joyid from joy where joyid = $id";
my $sth_chk = &execsql($dbh, $sql_chk);

while ( my ($joyid) = $sth_chk->fetchrow() ) {
$db_joyid{$joyid} = $joyid;
}
if ($db_joyid{$id}) {
print "\n\t"."数据库数据重复:".$title."\n";
#$jj++;
}else{
my $sql_insert = "insert into joy (`title`,`intro`,`tags`,`image_1`,`src_image`,`joyid`,`category`,`length`,`createdate`,`createtime`,`playurl`) values ($title,$intro,$tags,'$image','$src_image','$id','$cat','$time','$curdate','$curtime','$play_url');";
my $sth_insert = &execsql($dbh, $sql_insert);
print "\n\t"."数据插入成功:".$title."\n";
$sth_insert->finish();
#$ii++;
}
$sth_chk->finish();
undef %db_joyid;
}
}
}
#print "总共插入$ii条数据,另有$jj条数据重复!";

sub get_time {
my ($sec,$min,$hour,$day,$mon,$year)=localtime(time);
$sec = ($sec < 10)?"0$sec":$sec;
$min = ($min < 10)?"0$min":$min;
$hour = ($hour < 10)?"0$hour":$hour;
$day = ($day < 10)?"0$day":$day;
$mon = ($mon < 9)?"0".($mon+1):($mon+1);
$year += 1900;
return "$year-$mon-$day", "$hour:$min:$sec";
}

sub get_joy_db {
my ( $db_host, $db_name, $db_user, $db_pwd, $db_port, $db_timeout ) =
( "xxxxxxxxxxxxxxx", "movie", "root", "xxxxxxxxx", 9002, 0 );
my $dbh =
&db_open( $db_host, $db_name, $db_user, $db_pwd, $db_port, $db_timeout );
return $dbh;
}

sub file_name {
my ($filepath) = @_;
my $pos = rindex( $filepath, "/" );
if ( $pos == -1 ) {
return $filepath;
}
else {
return substr( $filepath, $pos + 1 );
}
}

sub md5_filename{
my ($filename) = @_;
#print $filename;
my $pos = rindex($filename,".");
#print $pos."\n";
my $prename = substr($filename,0,$pos);
my $extname = substr($filename,$pos+1);
return md5_hex($prename).".".$extname;
}

sub handleJoyPic {
my ($arg,$partner) = @_;
if ( $arg !~ /http:\/\/.*/isg ) {
return "";
}
my $img_filename = file_name($arg);
my $md5_filename = md5_filename($img_filename);
my $hash = md5_hex($arg);
my $len = length($hash);
my $ascii = 0;
for ( my $i = 0 ; $i < $len ; $i++ ) {
$ascii += ord( substr( $hash, $i, 1 ) );
}
my $path = sprintf( "%d/%d", $ascii % 128, $ascii % 53 );
my $fixed_img_path = "$partner/$path/$md5_filename";
my $cmd = "mkdir -p $partner/$path/;wget $arg;mv $img_filename $partner/$path/$md5_filename";
$cmd .=";/usr/local/bin/rsync -vtp --timeout=120 -R $fixed_img_path xxxxxxxxx::img_mdb";
#print $cmd."\n";
system("$cmd");
#print $fixed_img_path."\n";
return $fixed_img_path;
}

sub return_url_update{
my ($url,$num) = @_;
if (!$num) {
$num = 50;
}
$url = $url."&start=0&num=".$num;
return $url;
}
...全文
463 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
我2我骄傲 2011-03-15
  • 打赏
  • 举报
回复
好多,懒的看了
iambic 2011-03-10
  • 打赏
  • 举报
回复
我觉得你要做的是尽量把代码删减。越少越好。最后只剩下几行代码,问题就比较清楚了。而且因为代码已经删减得没什么用处,可以完整贴出来给其他人重现了。别人手头根本重现不出来你的问题,帮不上什么忙。
wish4sun 2011-03-10
  • 打赏
  • 举报
回复
我发现在解析XML其中的几条数据的时候就会停止不动,造成out of memory,但是我实在看不出来那条数据到底哪儿有问题,不知道perl有没有检查xml数据方面的函数
iambic 2011-03-08
  • 打赏
  • 举报
回复
一条数据就out of memory?有没有死循环或者递归?CPU占用情况呢?
wish4sun 2011-03-08
  • 打赏
  • 举报
回复
这一条数据有的时候是可以读过去的,所以我认为数据本身并没有问题,假如我将那四个数据接口分别执行,那么就可以读过去,但是放到一个哈希表里面去循环,就不行了。说实话,我对内存什么的没什么概念,而且又是perl的新手,不太会调试perl,所以才到这里问一下的。。。倒不是我不想自己找,我都找了2天了,还是没找到。。。
iambic 2011-03-08
  • 打赏
  • 举报
回复
“直到遇到某一条数据后”是哪一条数据?自己仔细看看这条数据有什么特别,对程序流程有什么影响。
也可以自己把代码一行行注释掉重新运行,看看哪些代码影响内存运行。
你自己也要对你的程序有概念,这个程序在运行过程中的内存使用应该是什么情况,有哪些状态是持续增长,那些是使用后就可以很快回收的。有没有很大的数据,有没有循环引用。
wish4sun 2011-03-08
  • 打赏
  • 举报
回复
我这个代码有读写数据库的操作和调用合作方数据接口,所以不能直接运行啊,数据库和接口相关信息我都给隐去了。我觉得就是可能是我哪个循环或者某个变量没弄好,导致没有释放内存,但是我实在是查不出来是哪儿的问题了,所以在这里求答案。
iambic 2011-03-08
  • 打赏
  • 举报
回复
别人直接运行你这段代码就能重现你的问题吗?
fibbery 2011-03-08
  • 打赏
  • 举报
回复
你该确定,在执行那段程序时,导致内存不断的增加。
fibbery 2011-03-08
  • 打赏
  • 举报
回复
在主程序的各个循环的开始,把循环变量打印出来,观察一下。
This is the third in O'Reilly's series of landmark Perl tutorials, which started with "Learning Perl", the bestselling introduction that taught you the basics of Perl syntax, and "Intermediate Perl", which taught you how to create re-usable Perl software. "Mastering Perl" pulls everything together to show you how to bend Perl to your will. Assuming you're familiar with concepts from the first two books - such as basic syntax, nested data structures, and the use of modules - "Mastering Perl" provides the next logical stage of Perl expertise by conveying its models and programming idioms. This book isn't a collection of clever tricks, but a way of thinking about Perl programming so you can integrate the real-life problems of debugging, maintenance, configuration, and other tasks you encounter as a working programmer. The book explains how to: use advanced regular expressions, including global matches, lookarounds, readable regexes, and regex debugging; avoid common programing problems with secure programming techniques; debug Perl with the Perl debugger, write your own debugger, and use debuggers others wrote; profile Perl to find out where you should concentrate your efforts before setting out to improve your program; benchmark Perl to figure out which implementations do better on time, memory, and other metrics - and cautions about what your numbers actually mean; wrangle Perl code to make it more presentable and readable by using M or M; symbol tables and typeglobs - How Perl keeps track of package variables and how you can use that mechanism for some powerful Perl tricks; define subroutines on the fly and turn the tables on normal procedural programming; and iterate through subroutine lists rather than data to make your code more effective and easy to maintain. It also includes topics such as: modify and jury rig modules to fix code without editing the original source; let your users configure your programs without touching the code; detect and reporting errors by learning how Perl reports errors, how you can detect errors Perl doesn't report, and how to tell your users about them; let your Perl program talk back to you by using Log4perl; store data for later use in another program, a later run of the same program, or to send as text over a network; work with Pod to translate plain ol' documentation into any format that you like, and test it, too; use bit operations and bit vectors to efficiently store large data; implement your own versions of Perl's basic data types to perform fancy operations without getting in the user's way; and write programs as modules to get all of the benefit of Perl's module distribution, installation, and testing tools. The appendices include "Brian's Guide to Solving Any Perl Problem" to improve your troubleshooting skills, as well as suggested reading to continue your Perl education. "Mastering Perl" starts you on your path to becoming the person with the answers, and, failing that, the person who knows how to find the answers or discover the problem.

37,720

社区成员

发帖
与我相关
我的任务
社区描述
JavaScript,VBScript,AngleScript,ActionScript,Shell,Perl,Ruby,Lua,Tcl,Scala,MaxScript 等脚本语言交流。
社区管理员
  • 脚本语言(Perl/Python)社区
  • IT.BOB
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧