草庐IT

xml - 使用 Perl XML::Twig 处理程序处理大文件的内存使用效率低下

coder 2024-06-27 原文

我偶尔需要从大型 XML 数据库导出中提取数据。文件大小在 600 到 700 MB 之间。经过几天的研究,我得出结论 XML::Twig是要走的路,因为它的处理程序允许我逐块处理文件。

我按照示例进行操作,经过数小时的反复试验,我编写了执行我需要完成的工作的 Perl 代码。代码有效,它提取了我想要的数据并计算了我需要的细节。但是在运行脚本时(处理 620MB 的 XML 需要大约 15 分钟),我在事件监视器中注意到,到最后内存使用率迅速增加到不合理的高水平。

我删除了处理我感兴趣的 XML 标签的 Perl 代码,并用一条指令替换它来增加一个变量,只需计算 product 的数量。元素已被发现。内存使用情况类似。首先是正常的,然后是最后几个元素,它开始迅速增加并吃掉我拥有的一切。

我添加了一些代码来监视时间、处理的项目数以及我的 Perl 进程使用了​​多少内存。此代码显示在此处:

#!/usr/bin/perl

use strict;
use utf8;

use XML::Twig;

binmode STDOUT, ":encoding(UTF-8)";
binmode STDERR, ":encoding(UTF-8)";

my $my_processID = $$;
my ($xml_file_name, $second_arg) = @ARGV;
unless (defined($xml_file_name)) { die "Please provide XML filename as 1st argument."; }

my $product_counter = 0;
my @shell_command_output_text;
my $resource_usage_status;
my $reference_timestamp;
my $datetimeNow;

my $t = XML::Twig->new(
    twig_handlers => { 'product' => \&do_what_needs_to_be_done_with_each_product },
    pretty_print  => 'indented'
);

$reference_timestamp = time();

$t->parsefile( $xml_file_name, ErrorContext => 2 );
print "(Parse finished)\n"; 
showstatus();
$t->purge;

print "(Purge finished)\n"; 
showstatus();
print "\nJOB COMPLETE.\n$product_counter items processed.\n";

exit 0;

sub do_what_needs_to_be_done_with_each_product() {
    my( $twig, $product)= @_;

    $product_counter++;

    ## Display status every 5 seconds:
    if ( ( time()-$reference_timestamp ) > 5 ) {
        showstatus();
        $reference_timestamp = time();
    }

    $twig->purge;
} ## end-sub


sub showstatus() {

    @shell_command_output_text = `top -l 1 -pid $my_processID -stats pid,command,cpu,mem`;

    ## I only need the last line of that output.
    $resource_usage_status = $shell_command_output_text[$#shell_command_output_text];
    $datetimeNow = localtime();
    chomp $resource_usage_status;

    print "Res: $resource_usage_status -> item count: $product_counter <- time: $datetimeNow\n";
} ## end-sub

这是我运行上述脚本时在屏幕上显示的内容。
keve@deimos:DATA$ ./twigExample.pl product_db_extract.xml 
Res: 3237  perl5.18 0.0  12M+ -> item count: 3086 <- time: Sat Nov 18 23:45:48 2017
Res: 3237  perl5.18 0.0  12M+ -> item count: 6521 <- time: Sat Nov 18 23:45:55 2017
Res: 3237  perl5.18 0.0  12M+ -> item count: 9909 <- time: Sat Nov 18 23:46:02 2017
Res: 3237  perl5.18 0.0  12M+ -> item count: 12751 <- time: Sat Nov 18 23:46:09 2017
Res: 3237  perl5.18 0.0  12M+ -> item count: 15570 <- time: Sat Nov 18 23:46:16 2017
Res: 3237  perl5.18 0.0  12M+ -> item count: 18151 <- time: Sat Nov 18 23:46:23 2017
Res: 3237  perl5.18 0.0  12M+ -> item count: 20828 <- time: Sat Nov 18 23:46:30 2017
Res: 3237  perl5.18 0.0  12M+ -> item count: 23561 <- time: Sat Nov 18 23:46:37 2017
Res: 3237  perl5.18 0.0  12M+ -> item count: 26230 <- time: Sat Nov 18 23:46:44 2017
Res: 3237  perl5.18 0.0  12M+ -> item count: 28861 <- time: Sat Nov 18 23:46:51 2017
Res: 3237  perl5.18 0.0  12M+ -> item count: 31665 <- time: Sat Nov 18 23:46:58 2017
Res: 3237  perl5.18 0.0  13M+ -> item count: 34443 <- time: Sat Nov 18 23:47:05 2017
Res: 3237  perl5.18 0.0  13M+ -> item count: 36952 <- time: Sat Nov 18 23:47:12 2017
Res: 3237  perl5.18 0.0  13M+ -> item count: 39461 <- time: Sat Nov 18 23:47:19 2017
Res: 3237  perl5.18 0.0  13M+ -> item count: 42113 <- time: Sat Nov 18 23:47:26 2017
Res: 3237  perl5.18 0.0  13M+ -> item count: 44794 <- time: Sat Nov 18 23:47:33 2017
Res: 3237  perl5.18 0.0  13M+ -> item count: 47510 <- time: Sat Nov 18 23:47:40 2017
Res: 3237  perl5.18 0.0  15M+ -> item count: 50154 <- time: Sat Nov 18 23:47:47 2017
Res: 3237  perl5.18 0.0  15M+ -> item count: 52869 <- time: Sat Nov 18 23:47:54 2017
Res: 3237  perl5.18 0.0  15M+ -> item count: 55497 <- time: Sat Nov 18 23:48:01 2017
Res: 3237  perl5.18 0.0  15M+ -> item count: 57725 <- time: Sat Nov 18 23:48:08 2017
Res: 3237  perl5.18 0.0  15M+ -> item count: 59754 <- time: Sat Nov 18 23:48:15 2017
Res: 3237  perl5.18 0.0  15M+ -> item count: 61600 <- time: Sat Nov 18 23:48:22 2017
Res: 3237  perl5.18 0.0  15M+ -> item count: 63244 <- time: Sat Nov 18 23:48:29 2017
Res: 3237  perl5.18 0.0  15M+ -> item count: 64801 <- time: Sat Nov 18 23:48:36 2017
Res: 3237  perl5.18 0.0  15M+ -> item count: 66448 <- time: Sat Nov 18 23:48:43 2017
Res: 3237  perl5.18 0.0  15M+ -> item count: 68022 <- time: Sat Nov 18 23:48:50 2017
Res: 3237  perl5.18 0.0  15M+ -> item count: 69561 <- time: Sat Nov 18 23:48:57 2017
Res: 3237  perl5.18 0.0  15M+ -> item count: 71180 <- time: Sat Nov 18 23:49:04 2017
Res: 3237  perl5.18 0.0  15M+ -> item count: 73009 <- time: Sat Nov 18 23:49:11 2017
Res: 3237  perl5.18 0.0  15M+ -> item count: 75259 <- time: Sat Nov 18 23:49:18 2017
Res: 3237  perl5.18 0.0  15M+ -> item count: 77331 <- time: Sat Nov 18 23:49:25 2017
Res: 3237  perl5.18 0.0  15M+ -> item count: 79344 <- time: Sat Nov 18 23:49:32 2017
Res: 3237  perl5.18 0.0  15M+ -> item count: 81389 <- time: Sat Nov 18 23:49:39 2017
Res: 3237  perl5.18 0.0  15M+ -> item count: 83345 <- time: Sat Nov 18 23:49:46 2017
Res: 3237  perl5.18 0.0  15M+ -> item count: 85346 <- time: Sat Nov 18 23:49:53 2017
Res: 3237  perl5.18 0.0  15M+ -> item count: 87350 <- time: Sat Nov 18 23:50:00 2017
Res: 3237  perl5.18 0.0  15M+ -> item count: 89359 <- time: Sat Nov 18 23:50:07 2017
Res: 3237  perl5.18 0.0  15M+ -> item count: 91374 <- time: Sat Nov 18 23:50:14 2017
Res: 3237  perl5.18 0.0  15M+ -> item count: 93451 <- time: Sat Nov 18 23:50:21 2017
Res: 3237  perl5.18 0.0  15M+ -> item count: 95542 <- time: Sat Nov 18 23:50:28 2017
Res: 3237  perl5.18 0.0  15M+ -> item count: 97635 <- time: Sat Nov 18 23:50:35 2017
Res: 3237  perl5.18 0.0  15M+ -> item count: 99764 <- time: Sat Nov 18 23:50:42 2017
Res: 3237  perl5.18 0.0  15M+ -> item count: 101914 <- time: Sat Nov 18 23:50:49 2017
Res: 3237  perl5.18 0.0  15M+ -> item count: 103896 <- time: Sat Nov 18 23:50:56 2017
Res: 3237  perl5.18 0.0  15M+ -> item count: 105982 <- time: Sat Nov 18 23:51:03 2017
Res: 3237  perl5.18 0.0  15M+ -> item count: 108023 <- time: Sat Nov 18 23:51:10 2017
Res: 3237  perl5.18 0.0  15M+ -> item count: 110090 <- time: Sat Nov 18 23:51:17 2017
Res: 3237  perl5.18 0.0  15M+ -> item count: 112033 <- time: Sat Nov 18 23:51:24 2017
Res: 3237  perl5.18 0.0  15M+ -> item count: 114039 <- time: Sat Nov 18 23:51:31 2017
Res: 3237  perl5.18 0.0  15M+ -> item count: 116038 <- time: Sat Nov 18 23:51:38 2017
Res: 3237  perl5.18 0.0  15M+ -> item count: 118031 <- time: Sat Nov 18 23:51:45 2017
(Parse finished)
Res: 3237  perl5.18 0.0  3780M+ -> item count: 119335 <- time: Sat Nov 18 23:54:21 2017
(Purge finished)
Res: 3237  perl5.18 0.0  2634M+ -> item count: 119335 <- time: Sat Nov 18 23:54:27 2017

JOB COMPLETE.
119335 items processed.
keve@deimos:DATA$

注意打印“解析完成”的 3 分钟间隔。

我希望看到最后几个产品标签的内存使用量上升,就像我在事件监视器中看到的那样。但是打印的内存使用量(直到最后一个产品标签)是完全可以接受的 15 MB。这个输出中没有显示棘手的部分:只有缺少的 3 分钟时间和 3780M 表明在最终产品标签之后发生了一些奇怪的事情。

所以我写了一个 shell 脚本来跟踪最后丢失的 3 分钟内的内存使用情况。这是我在单独的窗口中运行的内容,而 perl 脚本正在其自己的窗口中处理 XML。
#!/bin/bash
while true
do
  perlStat=`top -l 1 -pid $1 -stats pid,command,cpu,mem,purg,vsize | grep perl5`
  echo "`date` ::> $perlStat"
  sleep 5
done

这是在 perl 脚本处理 XML 时运行的 shell 脚本的输出:
keve@deimos:DATA$ ./monitorTWIGprocess.sh 3237
2017 Nov 18 Szo 23:45:53 CET ::> 3237  perl5.18 0.0  12M+ 0B   N/A  
2017 Nov 18 Szo 23:46:00 CET ::> 3237  perl5.18 0.0  12M+ 0B   N/A  
2017 Nov 18 Szo 23:46:06 CET ::> 3237  perl5.18 0.0  12M+ 0B   N/A  
2017 Nov 18 Szo 23:46:12 CET ::> 3237  perl5.18 0.0  12M+ 0B   N/A  
2017 Nov 18 Szo 23:46:18 CET ::> 3237  perl5.18 0.0  12M+ 0B   N/A  
2017 Nov 18 Szo 23:46:24 CET ::> 3237  perl5.18 0.0  12M+ 0B   N/A  
2017 Nov 18 Szo 23:46:30 CET ::> 3237  perl5.18 0.0  12M+ 0B   N/A  
2017 Nov 18 Szo 23:46:36 CET ::> 3237  perl5.18 0.0  12M+ 0B   N/A  
2017 Nov 18 Szo 23:46:42 CET ::> 3237  perl5.18 0.0  12M+ 0B   N/A  
2017 Nov 18 Szo 23:46:48 CET ::> 3237  perl5.18 0.0  12M+ 0B   N/A  
2017 Nov 18 Szo 23:46:54 CET ::> 3237  perl5.18 0.0  12M+ 0B   N/A  
2017 Nov 18 Szo 23:47:01 CET ::> 3237  perl5.18 0.0  12M+ 0B   N/A  
2017 Nov 18 Szo 23:47:07 CET ::> 3237  perl5.18 0.0  13M+ 0B   N/A  
2017 Nov 18 Szo 23:47:13 CET ::> 3237  perl5.18 0.0  13M+ 0B   N/A  
2017 Nov 18 Szo 23:47:19 CET ::> 3237  perl5.18 0.0  13M+ 0B   N/A  
2017 Nov 18 Szo 23:47:25 CET ::> 3237  perl5.18 0.0  13M+ 0B   N/A  
2017 Nov 18 Szo 23:47:31 CET ::> 3237  perl5.18 0.0  13M+ 0B   N/A  
2017 Nov 18 Szo 23:47:37 CET ::> 3237  perl5.18 0.0  13M+ 0B   N/A  
2017 Nov 18 Szo 23:47:43 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:47:49 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:47:56 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:48:02 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:48:08 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:48:14 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:48:20 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:48:26 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:48:32 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:48:38 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:48:44 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:48:51 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:48:57 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:49:03 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:49:09 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:49:15 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:49:21 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:49:27 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:49:33 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:49:39 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:49:46 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:49:52 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:49:58 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:50:04 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:50:10 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:50:16 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:50:22 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:50:28 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:50:35 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:50:41 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:50:47 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:50:53 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:50:59 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:51:05 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:51:11 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:51:17 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:51:23 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:51:29 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:51:36 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:51:42 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:51:48 CET ::> 3237  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 18 Szo 23:51:54 CET ::> 3237  perl5.18 0.0  125M+ 0B   N/A  
2017 Nov 18 Szo 23:52:00 CET ::> 3237  perl5.18 0.0  278M+ 0B   N/A  
2017 Nov 18 Szo 23:52:06 CET ::> 3237  perl5.18 0.0  430M+ 0B   N/A  
2017 Nov 18 Szo 23:52:12 CET ::> 3237  perl5.18 0.0  584M+ 0B   N/A  
2017 Nov 18 Szo 23:52:18 CET ::> 3237  perl5.18 0.0  737M+ 0B   N/A  
2017 Nov 18 Szo 23:52:24 CET ::> 3237  perl5.18 0.0  889M+ 0B   N/A  
2017 Nov 18 Szo 23:52:31 CET ::> 3237  perl5.18 0.0  1042M+ 0B   N/A  
2017 Nov 18 Szo 23:52:37 CET ::> 3237  perl5.18 0.0  1195M+ 0B   N/A  
2017 Nov 18 Szo 23:52:43 CET ::> 3237  perl5.18 0.0  1349M+ 0B   N/A  
2017 Nov 18 Szo 23:52:49 CET ::> 3237  perl5.18 0.0  1502M+ 0B   N/A  
2017 Nov 18 Szo 23:52:55 CET ::> 3237  perl5.18 0.0  1656M+ 0B   N/A  
2017 Nov 18 Szo 23:53:01 CET ::> 3237  perl5.18 0.0  1809M+ 0B   N/A  
2017 Nov 18 Szo 23:53:07 CET ::> 3237  perl5.18 0.0  1961M+ 0B   N/A  
2017 Nov 18 Szo 23:53:13 CET ::> 3237  perl5.18 0.0  2114M+ 0B   N/A  
2017 Nov 18 Szo 23:53:19 CET ::> 3237  perl5.18 0.0  2267M+ 0B   N/A  
2017 Nov 18 Szo 23:53:26 CET ::> 3237  perl5.18 0.0  2420M+ 0B   N/A  
2017 Nov 18 Szo 23:53:32 CET ::> 3237  perl5.18 0.0  2573M+ 0B   N/A  
2017 Nov 18 Szo 23:53:38 CET ::> 3237  perl5.18 0.0  2726M+ 0B   N/A  
2017 Nov 18 Szo 23:53:44 CET ::> 3237  perl5.18 0.0  2879M+ 0B   N/A  
2017 Nov 18 Szo 23:53:50 CET ::> 3237  perl5.18 0.0  3032M+ 0B   N/A  
2017 Nov 18 Szo 23:53:56 CET ::> 3237  perl5.18 0.0  3186M+ 0B   N/A  
2017 Nov 18 Szo 23:54:02 CET ::> 3237  perl5.18 0.0  3339M+ 0B   N/A  
2017 Nov 18 Szo 23:54:08 CET ::> 3237  perl5.18 0.0  3492M+ 0B   N/A  
2017 Nov 18 Szo 23:54:15 CET ::> 3237  perl5.18 0.0  3646M+ 0B   N/A  
2017 Nov 18 Szo 23:54:21 CET ::> 3237  perl5.18 0.0  3786M+ 0B   N/A  
2017 Nov 18 Szo 23:54:27 CET ::> 3237  perl5.18 0.0  3502M+ 0B   N/A  
2017 Nov 18 Szo 23:54:33 CET ::> 
^C
keve@deimos:DATA$

请注意 23:51:54 内存使用量的增加。那是另一个输出中 3 分钟的间隔开始的时候。并且内存使用量从那里迅速上升。

我很困惑是什么导致了在处理最后一个(第 119,335 个)产品标签结束时内存使用量的快速增加。不管它是什么,为什么它使用这么多内存? 3.5G而不是15M,那不行。

难道我做错了什么?

关于如何避免内存使用量增加的任何建议?

稍后添加,以回应我的原始帖子收到的答案。

补充
切换到 twig_roots。
我通过注释掉处理程序定义并添加其 twig_roots 变量来修改 twig 处理程序块,如下所示:
my $t = XML::Twig->new(
        ##twig_handlers => { 'product' => \&do_what_needs_to_be_done_with_each_product },
        twig_roots => { 'product' => \&do_what_needs_to_be_done_with_each_product },
        twig_print_outside_roots => 0,
        pretty_print => 'indented'
        );

我离开了$twig->purge();我的潜艇内的指令。

这是 perl 脚本的输出:
keve@deimos:DATA$ ./twigExample.pl product_db_extract.xml 
Res: 1591  perl5.18 0.0  12M+ -> item count: 2852 <- time: Sun Nov 19 15:20:51 2017
Res: 1591  perl5.18 0.0  12M+ -> item count: 6106 <- time: Sun Nov 19 15:20:58 2017
Res: 1591  perl5.18 0.0  12M+ -> item count: 9341 <- time: Sun Nov 19 15:21:05 2017
Res: 1591  perl5.18 0.0  12M+ -> item count: 12141 <- time: Sun Nov 19 15:21:12 2017
.
.
.
Res: 1591  perl5.18 0.0  15M+ -> item count: 112293 <- time: Sun Nov 19 15:26:41 2017
Res: 1591  perl5.18 0.0  15M+ -> item count: 114255 <- time: Sun Nov 19 15:26:48 2017
Res: 1591  perl5.18 0.0  15M+ -> item count: 116171 <- time: Sun Nov 19 15:26:55 2017
Res: 1591  perl5.18 0.0  15M+ -> item count: 118099 <- time: Sun Nov 19 15:27:02 2017
(Parse finished)
Res: 1591  perl5.18 0.0  15M+ -> item count: 119335 <- time: Sun Nov 19 15:27:56 2017
(Purge finished)
Res: 1591  perl5.18 0.0  15M+ -> item count: 119335 <- time: Sun Nov 19 15:27:57 2017

JOB COMPLETE.
119335 items processed.
keve@deimos:DATA$

这是监控 shell 脚本的输出:
keve@deimos:DATA$ ./monitorTWIGprocess.sh 1591
2017 Nov 19 Vas 15:20:57 CET ::> 1591  perl5.18 0.0  12M+ 0B   N/A  
2017 Nov 19 Vas 15:21:03 CET ::> 1591  perl5.18 0.0  12M+ 0B   N/A  
2017 Nov 19 Vas 15:21:09 CET ::> 1591  perl5.18 0.0  12M+ 0B   N/A  
2017 Nov 19 Vas 15:21:16 CET ::> 1591  perl5.18 0.0  12M+ 0B   N/A  
2017 Nov 19 Vas 15:21:22 CET ::> 1591  perl5.18 0.0  12M+ 0B   N/A  
2017 Nov 19 Vas 15:21:28 CET ::> 1591  perl5.18 0.0  12M+ 0B   N/A  
2017 Nov 19 Vas 15:21:34 CET ::> 1591  perl5.18 0.0  12M+ 0B   N/A  
2017 Nov 19 Vas 15:21:40 CET ::> 1591  perl5.18 0.0  12M+ 0B   N/A  
2017 Nov 19 Vas 15:21:46 CET ::> 1591  perl5.18 0.0  12M+ 0B   N/A  
2017 Nov 19 Vas 15:21:52 CET ::> 1591  perl5.18 0.0  12M+ 0B   N/A  
2017 Nov 19 Vas 15:21:58 CET ::> 1591  perl5.18 0.0  12M+ 0B   N/A  
2017 Nov 19 Vas 15:22:04 CET ::> 1591  perl5.18 0.0  12M+ 0B   N/A  
2017 Nov 19 Vas 15:22:10 CET ::> 1591  perl5.18 0.0  12M+ 0B   N/A  
2017 Nov 19 Vas 15:22:16 CET ::> 1591  perl5.18 0.0  13M+ 0B   N/A  
2017 Nov 19 Vas 15:22:22 CET ::> 1591  perl5.18 0.0  13M+ 0B   N/A  
2017 Nov 19 Vas 15:22:28 CET ::> 1591  perl5.18 0.0  13M+ 0B   N/A  
2017 Nov 19 Vas 15:22:35 CET ::> 1591  perl5.18 0.0  13M+ 0B   N/A  
2017 Nov 19 Vas 15:22:41 CET ::> 1591  perl5.18 0.0  13M+ 0B   N/A  
2017 Nov 19 Vas 15:22:47 CET ::> 1591  perl5.18 0.0  13M+ 0B   N/A  
2017 Nov 19 Vas 15:22:53 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:22:59 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:23:05 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:23:11 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:23:17 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:23:23 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:23:29 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:23:35 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:23:41 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:23:47 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:23:54 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:24:00 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:24:06 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:24:12 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:24:18 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:24:24 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:24:30 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:24:36 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:24:42 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:24:48 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:24:54 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:25:00 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:25:06 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:25:13 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:25:19 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:25:25 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:25:31 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:25:37 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:25:43 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:25:49 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:25:55 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:26:01 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:26:07 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:26:13 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:26:19 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:26:26 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:26:32 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:26:38 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:26:44 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:26:50 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:26:56 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:27:02 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:27:08 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:27:14 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:27:20 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:27:26 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:27:32 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:27:38 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:27:44 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:27:51 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:27:57 CET ::> 1591  perl5.18 0.0  15M+ 0B   N/A  
2017 Nov 19 Vas 15:28:03 CET ::> 
^C
keve@deimos:DATA$

好消息是使用 twig_roots 方法而不是 twig 处理程序可以使我的 perl 代码按照我想要的方式运行。它通过一个巨大的 XML 文件端从每个产品中提取数据(提取的数据不是 XML 格式的),同时使用的内存量保持在 20 兆字节以下。灿烂!
坏消息是我仍然无法解释为什么使用处理程序会占用那么多内存,以及为什么在读取最后一个产品后会这样做。直到最后一个产品,内存使用情况都很好。是什么让它在那个时候失控?我将进行更多测试以尝试满足我的好奇心,但这不再与我的 XML 处理 perl 代码开发如何向前发展有关。我将 twig_roots 建议标记为可接受的答案,但我也非常感谢另一个答案,因为该答案具有同等的教育意义。

最佳答案

您正在构建一个完整的 XML 数据结构,除了 product元素,只在最后丢弃它

你没有说你真正想用数据做什么,但如果你提供 twig_handlers然后 XML::Twig期望生成输入数据的过滤/修改版本

如果您根本不需要任何输出 XML,或者您想构建自己的而不是修改输入,那么我建议您使用 twig_roots相反,像这样

这是未经测试的代码。我目前正在旅行,离 PC 系统很远,无法使用 进行测试

my $t = XML::Twig->new(
    twig_roots               => { product => \&do_what_needs_to_be_done_with_each_product },
    twig_print_outside_roots => 0,
    pretty_print             => 'indented',
); 

请注意 do_what_needs_to_be_done_with_each_product (我希望这不是真正的标识符)不应该包含 $t->purge当这样工作时

关于xml - 使用 Perl XML::Twig 处理程序处理大文件的内存使用效率低下,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47372689/

有关xml - 使用 Perl XML::Twig 处理程序处理大文件的内存使用效率低下的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  3. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  4. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  5. ruby - 在 Ruby 中使用匿名模块 - 2

    假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于

  6. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  7. ruby-on-rails - 在 Rails 中将文件大小字符串转换为等效千字节 - 2

    我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,

  8. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  9. ruby - 使用 ruby​​ 和 savon 的 SOAP 服务 - 2

    我正在尝试使用ruby​​和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我

  10. ruby - 在 Ruby 程序执行时阻止 Windows 7 PC 进入休眠状态 - 2

    我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0

随机推荐