私のスクリプトがますます多くのメモリを使用しているのはなぜですか?みどりのせいか?

私のスクリプトがますます多くのメモリを使用しているのはなぜですか?みどりのせいか?

私はさまざまなウェブサイトを無限ループで表示するスクリプトを書いており、システムがより多くのメモリをゆっくり消費していることを発見しました。それ以外の場合、スクリプトは完全に機能します。

コマンドで収集した内容によると、メモリの全部(少なくともかなりの部分)を消費するのはインターネットブラウザtopと考えられます。midori鉱山はmidori現在タブのすべてのページを開くように構成されているため、実行中のインスタンスは1つだけで、タブもmidori1つだけ開いていますが、まだメモリ使用量が増え続けています。

#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 midori2done行の間にあります。もしそうならpkill midori ; midori ${SITES[i]} &。またはforループで:[ "$i" == "${#SITES[@]}" ] && pkill midoribefore running midori。または 0 から $(("${#SITES[@]" - 1)) まで繰り返し、最初のdone

あるいは、おそらく最も簡単な方法はステートメントの直後にありますpkill midoriwhilemidoriが実行されていない場合はエラーメッセージが表示されず、runを使用しないと何も起こりませんset -e)。

インストールしていない場合pkill(debianとraspbianのパッケージにありますprocps)、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用にのみ使用し、他のものはまったく使用しません。興味のあるコンテンツをランダムに検索するには、ChromeとFirefoxを使用してください。

chromium本物の豚です。現在は10GBしか使用していませんが、アップグレードにより数時間前に再起動を行ったためです(以前は14GB程度でした)。繰り返しますが、firefox通常は約4〜6GBです。しかし、それぞれ12〜3個のタブと20個以上のウィンドウを使用して、数週間または数ヶ月間同時に実行しました。各ウィンドウは、主に私が読んでいる特定のトピックに関するものです。

実際にどのくらいのクロムが使用されているのかを見て、少しショックを受けました。それから「たった100ドルでRAMを32GBに倍増できる」と思いました。今私は本当に気にしません。マザーボードが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];
}

関連情報