我已经编写了一个服务,可以从外部合作伙伴网站下载文件。每个大约有1000个文件,每个1 MB。每当我达到大约800个文件时,我的进程就会内存不足。
我应该如何确定根本原因?
var request = require('sync-request');
var fs = require('graceful-fs')
function find_starting_url(xyz_category){
feed_url = "<url>"
response = request("GET", feed_url).getBody().toString()
response = JSON.parse(response)
apiListings = response['apiGroups']['affiliate']['apiListings']
starting_url = apiListings[xyz_category]['availableVariants']['v0.1.0']['get']
return starting_url
}
function get_all_files(feed_category, count, next_url, retry_count){
var headers = {
'Id': '<my_header>',
'Token': '<my key>'
}
console.log(Date())
console.log(count)
if(next_url){
products_url = next_url
}
else{
products_url = find_starting_url(feed_category)
}
try{
var products = request("GET", products_url, {"headers": headers}).getBody().toString()
var parsed = JSON.parse(products)
var home = process.env.HOME
var fd = fs.openSync(home + "/data/abc/xyz/" + feed_category + "/" + count + ".json", 'w')
fs.writeSync(fd, products)
fs.closeSync(fd)
next_url = parsed['nextUrl']
count++;
if(next_url){
get_all_files(feed_category, count, next_url)
}
}catch(e){
if(retry_count >= 5){
console.log("TERRIBLE ENDING!!!", e)
}else{
retry_count++;
console.log("some error... retrying ..", e)
get_all_files(feed_category, count, next_url, retry_count)
}
}
}
var feed_category = process.argv[2]
get_all_files(feed_category, 1)
答案 0 :(得分:4)
您以递归方式调用同步函数,因此您拥有的每个请求和每个请求的所有数据都会保留在本地变量的内存中,直到完成所有请求并且所有递归调用都可以展开然后最后释放所有局部变量集。这需要大量的内存(正如你所发现的那样)。
最好重新构建代码,以便处理当前请求,写入磁盘,然后在进入下一个请求时保留该请求中的任何内容。最简单的方法是使用while循环而不是递归调用。在伪代码中:
initialize counter
while (more to do) {
process the next item
increment counter
}
我不了解您的代码尝试做什么以提出重写的详细信息,但希望您可以看到如何使用上面的非递归结构替换递归。
答案 1 :(得分:1)
这是因为您正在对get_all_files
函数执行递归调用,并且每次执行都会将body
变量保留在内存中,因为每个子执行都需要在内存释放之前完成。