Perl 为什么我的';使用my_模块';占用这么多堆内存?
此示例脚本:Perl 为什么我的';使用my_模块';占用这么多堆内存?,perl,memory,Perl,Memory,此示例脚本: #!/usr/bin/perl -w while (1) { sleep(1); } 大约需要264 kB grep -A1 heap /proc/9216/smaps 0817b000-081bd000 rw-p 0817b000 00:00 0 [heap] Size: 264 kB 但当我只添加模块时: #!/usr/bin/perl -w use my_module; while (1) { sleep(1
#!/usr/bin/perl -w
while (1)
{
sleep(1);
}
大约需要264 kB
grep -A1 heap /proc/9216/smaps
0817b000-081bd000 rw-p 0817b000 00:00 0 [heap]
Size: 264 kB
但当我只添加模块时:
#!/usr/bin/perl -w
use my_module;
while (1)
{
sleep(1);
}
它需要18092KB
grep -A1 heap /proc/9219maps
0817b000-09326000 rw-p 0817b000 00:00 0 [heap]
Size: 18092 kB
注意:“我的模块”有很多“使用模块;”里面
我怎么才能找到需要这么多记忆的东西
我怎样才能减少它?(使用“使用模块(功能)”)
谢谢您的帮助。您没有留下任何细节,但您已经回答了一个一般性问题:是的,使用大量模块会消耗大量内存,具体取决于这些模块是什么以及它们导入了什么。当然,如果使用更少的模块,或者有选择地导入符号(或者根本不导入符号),您将使用更少的内存
你能提供一个更具体的例子,说明某件东西消耗的内存比你认为的要多吗?回答:我怎样才能减少它?(使用“使用模块(功能)”)
当您需要使用“我的模块”中的每个模块时,可能只需要使用“require”,而不是大量的“use”。这就是我缩短时间/尺寸的方法。也就是说,如果您不需要在“我的模块”中“使用”的每一个模块 插入
开始{}
块以缩小罪犯的范围,如中所示
#! /usr/bin/perl
sub grep_heap { print @_, "\n"; system "grep -A1 heap /proc/$$/smaps" }
BEGIN { grep_heap "<null>" }
use warnings;
BEGIN { grep_heap "+warnings" }
use strict;
BEGIN { grep_heap "+strict" }
use Data::Dumper;
BEGIN { grep_heap "+Data::Dumper" }
use POSIX;
BEGIN { grep_heap "+POSIX" }
print "Hi\n";
perl-5.8.8的前几个违规者:
CPAN::Nox - 9.7 MiB
CPAN - 9.6 MiB
ExtUtils::MM_VMS - 5.3 MiB
CPAN::FirstTime - 5.2 MiB
ExtUtils::Installed - 5.2 MiB
B::CC - 5.2 MiB
bigrat - 4.9 MiB
Math::BigRat - 4.8 MiB
ExtUtils::MM_NW5 - 4.7 MiB
ExtUtils::MM_OS2 - 4.6 MiB
ExtUtils::MM_Win32 - 4.6 MiB
ExtUtils::MM_Win95 - 4.6 MiB
CPAN::Nox-9.7 MiB
CPAN-9.6mib
ExtUtils::MM_VMS-5.3 MiB
CPAN::FirstTime-5.2 MiB
ExtUtils::已安装-5.2 MiB
B::CC-5.2 MiB
大鼠-4.9 MiB
数学::BigRat-4.8mib
ExtUtils::MM_NW5-4.7 MiB
ExtUtils::MM_OS2-4.6 MiB
ExtUtils::MM_Win32-4.6 MiB
ExtUtils::MM_Win95-4.6 MiBBut use和require几乎是等效的,尽管每个都在不同的阶段运行:为什么这会减少大小?它只是在模块加载时发生变化,而不是如何加载(除非您不总是执行
require
语句)。我的意思是如果您不总是执行“require”语句。另外,“require”不导入符号,但无论如何也不应该大量导入符号。只导入你需要的东西,并责骂默认导出所有东西的模块。你的答案的第一个版本很棒,最后一个版本很棒!)谢谢我很乐意帮忙。那么你想让我们知道是哪些模块给你带来了麻烦吗?事实上,问题不在于具体的模块,而只是我模块中的一长串“用法”…:(我只是用更具体的‘用法’更新了我的代码,我已经将内存堆的使用率降低了13%!请记住:“不要滥用‘用法’!”:)
#! /usr/bin/perl
sub heap {
my($heap) = @_;
unless ($heap =~ /^([0-9a-f]+)-([0-9a-f]+)/m) {
warn "$0: unexpected heap:\n$heap";
return -1;
}
hex($2) - hex($1);
}
sub size {
my($bytes) = @_;
my @units = (
[ MiB => "%.1f", 1_024 * 1_024 ],
[ KiB => "%.1f", 1_024 ],
);
for (@units) {
my($unit,$fmt,$n) = @$_;
return sprintf "$fmt %s" => $bytes/$n, $unit
if $bytes >= $n;
}
return "$bytes byte" . ($bytes == 1 ? "" : "s");
}
my %incr;
my $perlmodlib = `perldoc -l perlmodlib`;
die "$0: perldoc failed" unless defined $perlmodlib;
my $base = heap `grep heap /proc/$$/smaps`;
warn "$0: base=" . size($base) . "\n";
chomp $perlmodlib;
open my $fh, "<", $perlmodlib or die "$0: open $perlmodlib: $!";
while (<$fh>) {
next unless /^=head2 Pragmatic Modules/ ..
/^=head2 Extension Modules/;
if (/^=item (\w+(::\w+)*)/) {
my $mod = $1;
(my $path = "$mod.pm") =~ s!::!/!g;
my $pid = open my $fh, "-|";
die "$0: fork: $!" unless defined $pid;
if ($pid == 0) {
open STDERR, ">", "/dev/null" or warn "$0: open: $!";
exec "perl", "-e", <<EOProgram;
BEGIN {
require \"$path\";
eval { $mod->import };
system qq(grep heap /proc/\$\$/smaps);
}
EOProgram
die "$0: exec: $!";
}
else {
local $/;
my $heap = <$fh>;
unless (defined $heap && length $heap) {
warn "$0: use $mod failed";
next;
}
$heap = heap $heap;
$incr{$mod} = $heap > 0 ? $heap-$base : $heap;
}
}
}
foreach my $mod (sort { $incr{$b} <=> $incr{$a} } keys %incr) {
print "$mod - ", size($incr{$mod}), "\n";
}
CPAN::Nox - 9.7 MiB
CPAN - 9.6 MiB
ExtUtils::MM_VMS - 5.3 MiB
CPAN::FirstTime - 5.2 MiB
ExtUtils::Installed - 5.2 MiB
B::CC - 5.2 MiB
bigrat - 4.9 MiB
Math::BigRat - 4.8 MiB
ExtUtils::MM_NW5 - 4.7 MiB
ExtUtils::MM_OS2 - 4.6 MiB
ExtUtils::MM_Win32 - 4.6 MiB
ExtUtils::MM_Win95 - 4.6 MiB