[英]Memory leak using WWW::Mechanize
我在 Perl 中有這個腳本,運行幾分鍾后出現"Out of memory"
錯誤。 我看不到任何循環引用,也無法弄清楚它發生的原因。
use feature 'say';
use WWW::Mechanize;
use HTML::TreeBuilder::XPath;
use utf8;
$url = "some url";
my $mech = new WWW::Mechanize;
$mech->get($url);
my $html = HTML::TreeBuilder::XPath->new_from_content($mech->content);
my $html2;
do {
for $item ($html->findnodes('//li[@class="dataset-item"]'))
{
my $title = $item->findvalue('normalize-space(.//a[2])');
next unless $title =~ /environmental impact statement/i;
my $link = $item->findvalue('.//a[2]/@href');
$mech->get($link);
$html2 = HTML::TreeBuilder::XPath->new_from_content($mech->content);
my @pdflinks = $html2->findvalues('//a[@title="Go to external URL"]/@href');
my $date = $html2->findvalue('//tr[th="Date Created"]/td');
for $pdflink (@pdflinks)
{
next unless $pdflink =~ /\.pdf$/;
$mech->get($pdflink);
$mech->save_content($filename = $mech->response->filename);
say "Title: $title\nDate: $date\nFilename: $filename\n";
}
}
if ($nextpage = $html->findvalue('//ul[@class="pagination"]/li/a[.="»"]/@href'))
{
say "Next Page: $nextpage\n";
$mech->get("some site" . $nextpage);
$html = HTML::TreeBuilder::XPath->new_from_content($mech->content);
}
} while ($nextpage);
say "Completed.";
由於WWW::Mechanize默認情況下其用戶代理在瀏覽時保留所有歷史記錄
- stack_depth =>
$value
設置跟蹤所有下載頁面的頁面堆棧的深度。 默認值實際上是無限堆棧大小。 如果堆棧耗盡了您的 memory,則將其設置為較小的數字,例如 5 或 10。將其設置為零意味着 Mech 將不保留任何歷史記錄。
因此 object 不斷增長。 通過使用Devel::Size qw(total_size)
我跟蹤$mech
的大小,以查看它在每個 pdf 之后增加了數十 kB。 而且腳本顯然有很多匹配項; 當它吞噬了 memory 的 10%(並且磁盤上有許多超過 Gb 的文件)時,我退出了我的測試。
然后一種解決方案是為每個$item
實例化一個新的 object 。 這在原則上是浪費的,但實際上並不會增加太多開銷,同時會限制最大大小。
或者重置它,或者確實限制它的堆棧深度。 由於代碼似乎不需要 go 回到以前的狀態,因此根本不需要任何堆棧,因此您刪除它的解決方案非常好。
注釋
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.