diff --git a/fhem/FHEM/98_fhemdebug.pm b/fhem/FHEM/98_fhemdebug.pm index b1da9b1a0..0331ceecd 100644 --- a/fhem/FHEM/98_fhemdebug.pm +++ b/fhem/FHEM/98_fhemdebug.pm @@ -37,8 +37,11 @@ fhemdebug_Fn($$) } elsif($param eq "status") { return "fhemdebug is ".($fhemdebug_enabled ? "enabled":"disabled"); + } elsif($param =~ m/^memusage/) { + return fhemdebug_memusage($param); + } else { - return "Usage: fhemdebug {enable|disable|status}"; + return "Usage: fhemdebug {enable|disable|status|memusage}"; } } @@ -96,6 +99,63 @@ fhemdebug_CallFn(@) } } + +sub +fhemdebug_memusage($) +{ + my ($param) = @_; + eval "use Devel::Size"; + return $@ if($@); + + $Devel::Size::warn = 0; + my @param = split(" ", $param); + my $max = 50; + my $re; + $max = pop(@param) if(@param > 1 && $param[$#param] =~ m/^\d+$/); + $re = pop(@param) if(@param > 1); + + my %ts; + my $collectSize = sub($$$) + { + my ($fn, $h, $mname) = @_; + return if($h->{__IN__CS__}); # save us from endless recursion + $h->{__IN__CS__} = 1; + eval { + foreach my $n (keys %$h) { + next if(!$n || $n =~ m/^[^A-Za-z]$/); + if($n =~ m/::$/) { + $fn->($fn, $h->{$n}, "$mname$n"); + next; + } + next if(main->can("$mname$n")); + + if($mname eq "main::" && + ($n eq "modules" || $n eq "defs" || $n eq "readyfnlist")) { + for my $mn (keys %{$main::{$n}}) { + $ts{"$mname$n::$mn"} = Devel::Size::total_size($main::{$n}{$mn}); + } + + } else { + $ts{"$mname$n"} = Devel::Size::total_size($h->{$n}); + + } + } + }; + delete $h->{__IN__CS__}; + Log 1, "collectSize $mname: $@" if($@); + }; + $collectSize->($collectSize, \%main::, "main::"); + + my @sts = sort { $ts{$b} <=> $ts{$a} } keys %ts; + my @ret; + for(my $i=0; $i < int(@sts); $i++) { + next if($re && $sts[$i] !~ m/$re/); + push @ret, sprintf("%4d. %-30s %8d", $i+1,substr($sts[$i],6),$ts{$sts[$i]}); + last if(@ret >= $max); + } + return join("\n", @ret); +} + 1; =pod @@ -107,17 +167,36 @@ fhemdebug_CallFn(@)

fhemdebug

=end html