Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 使用WWW::Mechanize执行重复查询时内存泄漏_Perl_Memory Leaks_Wikipedia Api_Www Mechanize - Fatal编程技术网

Perl 使用WWW::Mechanize执行重复查询时内存泄漏

Perl 使用WWW::Mechanize执行重复查询时内存泄漏,perl,memory-leaks,wikipedia-api,www-mechanize,Perl,Memory Leaks,Wikipedia Api,Www Mechanize,我试图在我的程序中找到内存泄漏。我已经找到了漏洞的来源,但我无法修复它 该程序读取与维基百科上的每个染色体相连的每个基因页面 该程序在每个基因页面上提取我感兴趣的信息,然后移动到下一个基因页面,依此类推 一旦到达当前染色体的基因列表的末尾,它就会移动到下一条染色体上,直到完成每一页 这个程序在我的电脑上运行到大约2-3周前。从那时起,它开始出现这个问题 我一直在使用top进行监控,随着程序的运行,内存使用明显增加,直到达到临界点,我的计算机崩溃 根据请求,我提供可编译的代码。我是从21号染色体开

我试图在我的程序中找到内存泄漏。我已经找到了漏洞的来源,但我无法修复它

该程序读取与维基百科上的每个染色体相连的每个基因页面

该程序在每个基因页面上提取我感兴趣的信息,然后移动到下一个基因页面,依此类推

一旦到达当前染色体的基因列表的末尾,它就会移动到下一条染色体上,直到完成每一页

这个程序在我的电脑上运行到大约2-3周前。从那时起,它开始出现这个问题

我一直在使用
top
进行监控,随着程序的运行,内存使用明显增加,直到达到临界点,我的计算机崩溃

根据请求,我提供可编译的代码。我是从21号染色体开始的,因为这一条的页数最少,因此花的时间最少。在这个代码片段中,内存使用仍然在递增,所以希望这就足够了!此外,eval语句也在其中,因为查询WikipediaAPI有时不会返回任何内容,而不是预期的JSON。eval函数允许我绕过这个问题,而不会让程序死掉

我的(更新的)代码 这段代码有一个更大的组件,但我排除了它,因为我知道这是问题的根源所在

使用
WWW::Mechanize的
while
循环部分

my $response = $mech->get($url)
已连接到内存泄漏

如果我删除该组件并运行该程序,内存使用保持不变,然后将其添加回显示内存再次增量增加

Perl版本:5.24.1

系统:Ubuntu 16.04

编辑:@Borodin谢谢你如此详尽的回复!不幸的是,我仍然注意到我的电脑内存泄漏,这让我怀疑是否还有更大的问题

它仍然会逐渐占用内存,目前我的电脑还可以,但当我运行包括一些网页抓取在内的完整程序时,我不知道我的电脑是否能够满足需要

有一点可能与此相关——我的电脑有一个奇怪的问题,它有时无法完全下载文件(尽管下载已完成,但文件被截断)。当我运行你的程序时,我经常遇到这样的错误:

**解析JSON字符串时出现意外的字符串结尾,字符偏移量5506(在“(字符串结尾)”之前)**


这似乎与我遇到的问题有关,我想知道这是否会导致内存泄漏问题?

您没有使用
WWW::Mechanize
LWP::UserAgent
没有提供的任何部分,因此我建议您遵循后者

下面是一些与您自己的程序几乎相同的工作代码。对我来说,它没有任何内存泄漏

请询问您是否需要任何解释;内容太多,无法贯穿整个节目

#!/usr/bin/env perl

use strict;
use warnings 'all';

use URI;
use URI::QueryParam;
use LWP;
use JSON::XS qw(decode_json);

STDOUT->autoflush;

my $api_root = URI->new( 'http://en.wikipedia.org/w/api.php' );

my @chromosomes = ( 1 .. 22, qw/ M Y X/ );

my $ua = LWP::UserAgent->new;

for my $chrom ( @chromosomes[20..$#chromosomes] ) {

    #print "The chromosome is $chrom\n";

    my $query = {
        action  => 'query',
        format  => 'json',
        list    => 'categorymembers',
        cmtitle => "Category:Genes on human chromosome $chrom",
        cmlimit => 'max',
    };

    my $url = $api_root->clone;
    $url->query_form( $query );

    my @gene_pages;

    while () {

        my $resp = $ua->get( $url );
        die $resp->status_line unless $resp->is_success;

        # J Source of malformed JSON string error
        my $data     = decode_json( $resp->decoded_content );
        my $query    = $data->{query};
        my $continue = $data->{continue};

        push @gene_pages, @{ $query->{categorymembers} };

        # Adapted code to new format for continuing queries
        last unless $continue;

        $url->query_param( cmcontinue => $continue->{cmcontinue} );
    }

    printf "Processing %d gene pages for chromosome %s\n",
            scalar @gene_pages,
            $chrom;

    my $gene_count;

    for my $gene_page ( @gene_pages ) {

        ++$gene_count;

        my $url = $api_root->clone;

        my $query = {
            action  => 'query',
            prop    => 'revisions',
            format  => 'json',
            rvprop  => 'content|tags|timestamp',
            pageids => $gene_page->{pageid}
        };

        $url->query_form( $query );

        # print "Requesting: $url\n";

        my $resp = $ua->get( $url );

        die $resp->status_line unless $resp->is_success;

        my $content = $resp->decoded_content;
        my $data    = decode_json( $content );    # J Source of malformed JSON string error

        print "$gene_count gene pages complete\n" unless $gene_count % 10;
    }

    print "There were $gene_count genes found for chromosome $chrom\n";
}

Mechanize保留它访问的每个页面的历史记录,默认情况下,它实际上是无限的。尝试将
stack\u depth
选项设置为较低的值,看看是否有帮助。感谢您的快速回复。我试着像这样使用堆栈深度:my$mech=WWW::Mechanize->new()$机械->堆叠深度(0);内存使用仍然显示相同的行为。WWW::Mechanize可能不是罪魁祸首吗?您必须始终
在编写的每个Perl程序的顶部使用strict
使用警告“all”
。这是调试的第一级,应该在你请求他人帮助之前采用。@simbabque:我不喜欢和,它们试图做类似的事情,主要是因为我每次都要查看它们所做的事情
common::sense
似乎是由希望Perl完全是另一种语言的人编写的。但事实是,我没有注意到
use
语句,是的,它涵盖了一些功能,但是
使用严格的“refs”
是必不可少的,因为符号引用是一个可怕的想法。当
时,它也
给定
,这是一个坏消息default@Borodinsense.pm.PL,其中
$ARGV[0]
设置为“sense.pm”。它为执行安装的perl版本生成适当的代码,将其写入
sense.pm
,并将
sense.pm
重命名为
sense.pm
#!/usr/bin/env perl

use strict;
use warnings 'all';

use URI;
use URI::QueryParam;
use LWP;
use JSON::XS qw(decode_json);

STDOUT->autoflush;

my $api_root = URI->new( 'http://en.wikipedia.org/w/api.php' );

my @chromosomes = ( 1 .. 22, qw/ M Y X/ );

my $ua = LWP::UserAgent->new;

for my $chrom ( @chromosomes[20..$#chromosomes] ) {

    #print "The chromosome is $chrom\n";

    my $query = {
        action  => 'query',
        format  => 'json',
        list    => 'categorymembers',
        cmtitle => "Category:Genes on human chromosome $chrom",
        cmlimit => 'max',
    };

    my $url = $api_root->clone;
    $url->query_form( $query );

    my @gene_pages;

    while () {

        my $resp = $ua->get( $url );
        die $resp->status_line unless $resp->is_success;

        # J Source of malformed JSON string error
        my $data     = decode_json( $resp->decoded_content );
        my $query    = $data->{query};
        my $continue = $data->{continue};

        push @gene_pages, @{ $query->{categorymembers} };

        # Adapted code to new format for continuing queries
        last unless $continue;

        $url->query_param( cmcontinue => $continue->{cmcontinue} );
    }

    printf "Processing %d gene pages for chromosome %s\n",
            scalar @gene_pages,
            $chrom;

    my $gene_count;

    for my $gene_page ( @gene_pages ) {

        ++$gene_count;

        my $url = $api_root->clone;

        my $query = {
            action  => 'query',
            prop    => 'revisions',
            format  => 'json',
            rvprop  => 'content|tags|timestamp',
            pageids => $gene_page->{pageid}
        };

        $url->query_form( $query );

        # print "Requesting: $url\n";

        my $resp = $ua->get( $url );

        die $resp->status_line unless $resp->is_success;

        my $content = $resp->decoded_content;
        my $data    = decode_json( $content );    # J Source of malformed JSON string error

        print "$gene_count gene pages complete\n" unless $gene_count % 10;
    }

    print "There were $gene_count genes found for chromosome $chrom\n";
}