请求进入Rails应用程序显着增加内存

时间:2015-03-27 13:20:01

标签: ruby-on-rails

我已经在我的Rails应用程序中发现了一个操作,每次运行时都会显着增加rails进程使用的内存。每次刷新屏幕时,内存使用量都会以恒定的百分比增加,直到服务器内存不足并且我被迫重启应用程序。

#show方法执行以下操作:

def show
  @report = Report.find(params[:id])
  @result = @report.results
  @result = @result.paginate(page: params[:page]) if @result

  respond_to do |format|
    format.html # run.html.erb
    format.json { redirect_to  "/results/#{@report.id}.json" }
    format.csv  { redirect_to  "/results/#{@report.id}.csv" }
  end
end

问题的代码行是@result = @report.results,它确实:

def results
  filename = "public/results/#{self.id}.json"
  if File.exists? filename
    the_results = File.read(filename)
    return JSON.parse(the_results)
  end
end

这里,问题是JSON.parse(the_results),其中.json文件可能非常大(示例文件为64 Mb)。看来我正在将整个文件加载到内存中以便将其传回控制器,然后控制器进行分页,这不是很好,因为如果我只想在视图中查看30条记录那么我不想加载所有内容。

我有两个问题:

  1. 为什么Rails'在这种情况下记忆会不断增加? FILE.read + JSON.parse为我的视图加载了所有内容,因此Rails会为此分配大量内存来执行此操作。当我再次这样做时,我希望将相同的内存(Rails进程可以自由使用)用于读取,而不是Rails从操作系统中获取更多内容?
  2. 有更好的方法吗?我想我只希望只调用一次FILE.read + JSON.parse,但它会在哪里缓存?控制器?
  3. 感谢您提供任何帮助,

    理查德

1 个答案:

答案 0 :(得分:0)

在rails框架中,默认情况下不会缓存读取文件及其内容已解析的部分。

如果可以的话,我建议从数据库表中而不是从文件中读取@report.results。我假设您没有将结果对象映射到活动记录模型。当你从数据库中获得缓存功能时,可能是一个好主意。

缓存FILE.read + JSON.parse活动在理论上是可行的,但我认为不切实际。如果自上次读取后文件已更改且文件大小和行数仍然相同,但某些行具有不同的内容,该怎么办?它仍然需要完整读取文件以确认内容没有改变。