我在我的 Rails 应用程序中发现了一个 Action ,每次运行它都会显着增加 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)。看来我正在将整个文件加载到内存中以便将其传递回 Controller ,然后 Controller 进行分页,这不好,因为如果我只想在 View 中查看 30 条记录,那么我不会想加载一切。我有两个问题:
FILE.read
+ JSON.parse
为我的 View 加载所有内容,因此 Rails 分配了大量内存来执行此操作。当我再次这样做时,我希望相同的内存(Rails 进程可以自由使用)用于读取,而不是 Rails 向操作系统要求更多? FILE.read
+ JSON.parse
只有一次,但它会被缓存在哪里? Controller ? 感谢您对此的任何帮助,
理查德
最佳答案
Rails 框架中默认可能不会缓存读取文件并解析其内容的部分。
如果有可能,我建议制作 @report.results
从数据库表而不是从文件中读取。我假设您还没有将结果对象映射到事件记录模型。这样做可能是个好主意,因为您可以从数据库中获得缓存功能。
缓存 FILE.read + JSON.parse
事件理论上是可能的,但我认为不切实际。如果自上次读取后文件已更改,并且文件大小和行数仍然相同,但某些行的内容不同,该怎么办?它仍然需要完整读取文件以确认内容没有更改。
关于ruby-on-rails - 请求 Rails 应用程序显着增加内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29301679/