Shell 通过PhantomJS运行JavaScript时内存不足

Shell 通过PhantomJS运行JavaScript时内存不足,shell,phantomjs,out-of-memory,Shell,Phantomjs,Out Of Memory,我的shell脚本是用cygwin for windows编写的: // main.sh #!/bin/bash [ "$#" -lt 1 ] && echo "Usage: thisscript.sh <filename.txt>" && exit 0 filename=`basename -s .txt $1` i=0 while [ $i == 0 ] do phantomjs --web-security=no myXHR.js $

我的shell脚本是用cygwin for windows编写的:

// main.sh
#!/bin/bash
[ "$#" -lt 1 ] && echo "Usage: thisscript.sh <filename.txt>" && exit 0
filename=`basename -s .txt $1`    
i=0
while [ $i == 0 ]
do
  phantomjs --web-security=no myXHR.js $filename.txt
  logLastLine=`tail -n 1 $filename.log`
  if [[ "$logLastLine" =~ "Error" ]]; then
    echo "Error occurs, now keep looping it..."
  elseif [[ "$logLastLine" =~ "503" ]]; then
    echo "Error occurs, now keep looping it..."
  elseif [[ "$logLastLine" =~ "500" ]]; then
    echo "Error occurs, now keep looping it..."
  else
    echo "Complete! Exiting the execution..."
    i=1
  fi
done
举例来说,由PhantomJS执行的javascript正在读取第一个参数(一个
filename.txt
文件),逐行传递到shell脚本中。对于每一行,它发送一个XMLHttpRequest来检查请求状态,并将其写入
filename.log
文件

错误状态号包括503和500。幸运的是,如果我重新发送相同的XMLHttpRequest,这些状态不太可能再次出现。因此,我需要做的是设置一个错误处理程序,用于在发生错误时重新发送相同的XMLHttpRequest

在这个错误处理程序中,我使用
X=${tail-n1log}
查看是否有错误状态号(包含“503”或“500”字符串)。例如,
if[[“$X”=~“503”];然后
通过不给出
i=1
和while循环永不退出来重新启动javascript的执行。直到它在没有任何错误状态号的情况下读取完导入文件的最后一行。 (我知道处理这样的错误很尴尬,但我想到了一个快速的解决方案。)

但这是理论上的。实际上,此脚本以错误“内存耗尽”结束。我估计这个错误是由
$1
文件中的大量行(>100k)触发的,它发生在JavaScript执行部分。我使用了
free-m
命令来获取内存使用信息,我注意到当Javascript运行时,使用的交换正在增加


有谁能教我在执行脚本时如何释放内存。

shell编程、Cygwin或其他程序中没有“干净内存命令”。shell执行的其中一个命令(可能是您没有显示的命令,隐藏在
#函数
后面的命令)占用了太多内存。您需要确定该命令是什么,为什么它使用了太多内存,并立即解决问题。您的错误无法用您提供的信息重现,因此无法对您的问题给出“正确”的答案。投票结束。@DevSolar好的,我理解。我想知道我是否提供了这个函数,问题会很复杂(包括由PhantomJS执行的javascript)。但如果需要,我会尽可能多地提供。很抱歉没有把问题说清楚。调试101:隔离问题。如果只运行Javascript部分,会发生这种情况吗?这将是非常重要的,并且需要对问题进行完全不同的标记。那么Bash脚本就无关紧要了。或者是
sed
在某一行上呕吐?哪一行?那将是一个
sed
问题,而不是Bash问题。诸如此类。感谢@DevSolar一直跟踪这个问题。你刚才的评论很有启发性。我认为
内存耗尽
消息是在PhantomJS执行部分给出的,因为它在
内存耗尽
消息之前不提供任何其他信息,正如PhantomJS应该提供的那样。尝试读取该文件,而不是一次读取所有文件。在shell编程、Cygwin或其他程序中没有“干净内存命令”。shell执行的其中一个命令(可能是您没有显示的命令,隐藏在
#函数
后面的命令)占用了太多内存。您需要确定该命令是什么,为什么它使用了太多内存,并立即解决问题。您的错误无法用您提供的信息重现,因此无法对您的问题给出“正确”的答案。投票结束。@DevSolar好的,我理解。我想知道我是否提供了这个函数,问题会很复杂(包括由PhantomJS执行的javascript)。但如果需要,我会尽可能多地提供。很抱歉没有把问题说清楚。调试101:隔离问题。如果只运行Javascript部分,会发生这种情况吗?这将是非常重要的,并且需要对问题进行完全不同的标记。那么Bash脚本就无关紧要了。或者是
sed
在某一行上呕吐?哪一行?那将是一个
sed
问题,而不是Bash问题。诸如此类。感谢@DevSolar一直跟踪这个问题。你刚才的评论很有启发性。我认为
内存耗尽
消息是在PhantomJS执行部分给出的,因为它在
内存耗尽
消息之前没有提供任何其他信息,正如PhantomJS应该提供的那样。尝试读取该文件,而不是一次全部读取。
// myXHR.js

phantom.onError = function(msg, trace) {
  console.log("PhantomJS Error");
  phantom.exit();
};


var fs = require('fs'), system = require('system');

if (system.args.length < 2) {
  console.log("Usage: myXHR.js <FILE>");
}

var content = '',
  f = null,
  lines = null,
  eol = "\n";

try {
  f = fs.open(system.args[1], "r");
  filename=system.args[1].replace(/\.txt/,"");
  content = f.read();
} catch (e) {
  console.log(e);
}

if (f) {
  f.close();
}

var request = new XMLHttpRequest();

if (content) {
  lines = content.split(eol);
  for (i=0; i<(lines.length-1);i++) {

  request.open('GET', "http://stackoverflow.com/", false);
  request.send();
  if (request.status === 200) {
    try { 
      fs.write($filename.log, line[i] + "Succeed!", 'a');
    } catch(e) {
      console.log(e);
    }
  } else {  
    try { 
      fs.write($filename.log, line[i] + "Error!", 'a');
    } catch(e) {
      console.log(e);
    }
  }
}
phantom.exit();