Shell 通过PhantomJS运行JavaScript时内存不足
我的shell脚本是用cygwin for windows编写的: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 $
// 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();