为什么我的脚本慢慢使用越来越多的内存?是因为米多里吗?

为什么我的脚本慢慢使用越来越多的内存?是因为米多里吗?

我编写了一个脚本来无限循环地显示各种网站,并注意到系统正在慢慢消耗越来越多的内存。否则该脚本可以完美运行。

从我从命令中收集到的信息来看top,我相信是midori(互联网浏览器)消耗了所有(嗯,至少是很大一部分)内存。我的midori配置为打开当前选项卡中的所有页面,因此只有一个midori运行实例,并且仅打开一个选项卡,但它仍然继续增加其内存使用量。

#Start VNC Server
x11vnc -display :0 -usepw -listen ip_addr &

#Sites to display
SITES=( "a bunch of urls here..." )
#Display Time (In Seconds)
TIME=( 125 35 35 35 35 35 20 20 20 20 20 20 20 20 20 30 )


#Open the browser and enter fullscreen mode
midori http://google.com &
sleep 15
xdotool key F11

#Infinite Loop
while [ 1 -eq 1 ]; do

#Loop through each site
for ((i=0;i<${#SITES[@]};++i)); do
        #Open the site
        midori ${SITES[i]} &

        #Check to see if the site has a display time set in the TIME variable
        if [ -z ${TIME[i]} ];
        then #If the display time is not set, display for 30 seconds
                sleep 30
        else #Display for the appropriate amount of time
                sleep ${TIME[i]}
        fi
done
done

有任何想法吗?谢谢。


编辑:
值得一提的是,当我说它“缓慢”使用更多内存时,我的意思是非常缓慢;运行脚本约 7 小时后,内存消耗从 35% 降至 61%。

答案1

Web 浏览器是臭名昭著的内存猪和内存泄漏者,尤其是当它们正在查看的页面包含任何 JavaScript 时。这只是他们本性的一部分。除了像 之类的文本模式浏览器之外lynx,我想我还没有见过这样的浏览器没有随着时间的推移会泄漏内存。

在显示最后一个选项卡后,您是否需要浏览器保留在屏幕上?如果不是,则pkill midori在两条done线之间。如果你这样做,那么pkill midori ; midori ${SITES[i]} &。或者,在for循环中:[ "$i" == "${#SITES[@]}" ] && pkill midori在运行之前midori。或从 0 循环到 $(("${#SITES[@]" - 1)),然后在第一个done.

或者,可能是最简单的,就在语句pkill midori之后while(如果 midori 没有运行,则不会打印任何错误消息,并且除非您使用 运行,否则什么也不会发生set -e)。

如果你没有pkill安装(它在procpsdebian 和 raspbian 上的软件包中),你可以在 midori 进程被杀死并重新启动时捕获它的 PID,并杀死该特定的 PID。例如

while [ 1 ]; do
  mPID=0

  for ((i=0;i<"${#SITES[@]}";++i)); do
    midori "${SITES[i]}" &
    [ "$mPID" -eq 0 ] && [ -n "$(jobs -n)" ] && mPID=$!
    [ "$mPID" -eq 0 ] && echo "couldn't start midori" && exit 1

    # sleep for for display time if set, otherwise 30 secs.
    [ -n "${TIME[i]}" ] && sleep "${TIME[i]}" || sleep 30
  done
  kill "$mPID"
done

这不仅可以获得任何的PID新的midori 进程已启动($!是最近后台作业的 PID),它会检查它是否已启动。如果 midori 由于任何原因无法运行,则会退出并显示错误消息。


如果您没有在 rpi 上运行,您可以为系统添加更多 RAM(如果可能的话)。这是提高系统性能和响应能力的一种相当便宜的方法,并且内核将使用任何“未使用”的 RAM 来缓存磁盘。


我编写了一个您可能会觉得有用的脚本,该脚本用于mem-pigs.sh统计指定程序的内存使用情况。默认为我经常使用的浏览器(因为它们占用内存)。

#! /bin/bash

# print total RSS memory usage for program(s) with multiple pids

# set default if no args
[ -z "$1" ] && set -- chromium firefox midori

for p in "$@" ; do
  printf "%s:\t%s %s\n" "$p" $( 
    ( printf '1024*(%s)\n' \
        $(awk '
               BEGIN {if (ARGC==1) { print 0 ; exit } };
               /VmRSS:/ {print $2}
              ' \
            $(pgrep "$p" | sed -e 's:^:/proc/:;s:$:/status:') | 
          paste -sd+)
    ) | 
      bc | 
      human-numbers.pl)
done

示例输出:

$ mem-pigs.sh
chromium:   9.81 GiB
firefox:    1.39 GiB
midori: 2.76 GiB

midori如果我将它用作通用浏览器,可能会使用更多,但我仅将它用于 Facebook,而不是其他。 chromium 和 firefox 用于随机浏览我感兴趣的内容。

chromium是真正的猪。它目前只使用 10GB,但那是因为我在几个小时前因为升级而重新启动了它(之前大约是 14GB)。同样firefox,通常在 4-6GB 左右。但我让它们同时运行数周或数月,每个窗口有十几个或三个选项卡,每个窗口有 20 个或更多窗口。每个窗口主要是关于我正在阅读的特定主题。

我有点震惊地看到到底使用了多少铬……然后我想“将我的 RAM 加倍到 32GB 只需 100 美元”。现在我真的不在乎了。如果我的主板是 DDR4 或者 32GB DDR3 DIMM 不是太贵的话,我会升级到 64GB。

mem-pigs.sh使用另一个脚本human-numbers.pl

#! /usr/bin/perl

use strict;
use warnings;

my $units = 1024;
my @suffixes=map { $_ ne 'B' && $_ } qw(B KiB MiB GiB TiB PiB EiB ZiB YiB);

if ( (@ARGV) && (($ARGV[0] eq '--si') || ($ARGV[0] eq '-s' )) ) {
  shift;
  $units = 1000;
  @suffixes=map { $_ ne 'B' && $_ } qw(B KB MB GB TB PB EB ZB YB);
};

# Use stdin and/or command-line args as input
# NOTE: command-line args are processed AFTER lines from stdin)
# TODO: option to process args BEFORE STDIN.
my @input = @ARGV;
@ARGV=();

if ( -p STDIN ) {
  while (<>) {
    push @input, $_;
  };
};

my $index=0;

for (@input) {
   my $n = $_ ;
   my $index = 0;

   for (@suffixes) {
     last  if $n < $units ;
     $n = $n / $units;
     $index++
   };

   printf "%.2f %s\n", $n, $suffixes[$index];
}

相关内容