【问题标题】:How to release memory from Sinatra App如何从 Sinatra App 中释放内存
【发布时间】:2012-08-03 21:46:11
【问题描述】:

使用 Sinatra 应用程序设置 api。

每个请求为 15MB。每次我刷新页面时,它都会增加 15MB 的内存。每次请求后如何清除信息?

require 'rubygems'
require 'sinatra'
require 'active_record'
require 'mysql2'
require 'json'

client = Mysql2::Client.new(adapter: 'mysql2', host: '127.0.0.1', database: 'dev_app', username: 'root', password: 'root')

get '/people' do
  q = "select name, age from people;"
  people = client.query(q, :as => :json).map{|one| {one['name'] => one['age'].to_i}}
  return people.to_json
  people = nil
end

【问题讨论】:

  • 你是如何知道内存去向的?您的 JSON 对象和 MySQL 连接有多大?您是否对您的应用程序进行了概要分析?这是由于内存限制导致的现实性能问题,还是只是抽象问题?
  • 从 Ruby PID 监控内存。我让它去,直到它达到 500+ MB。目前 JSON 对象为 @ 50K,但会增长。这对我来说是个问题,因为我想将内存保持在 100MB 以下,这样我就可以在 AWS 中运行多个实例。至于分析,现在尝试这样做,但这是我第一次尝试使用 Sinatra,所以试图弄清楚我需要导入什么。

标签: ruby activerecord sinatra


【解决方案1】:

简介、简介、简介

您尚未确定应用程序中实际消耗内存的内容。因此,您的问题是未定义的,任何“解决方案”都相当于在寻找潜在答案的过程中挣扎。

可能的答案

  1. 内存增长本质上不是问题,除非你真的用完了它。如果这没有发生,请不要理会它。
  2. mysql2 gem 有一些已知的内存问题。这可能适用于您的场景。
  3. Garbage collection 不会仅仅因为变量或文字超出范围而发生。有些情况会触发垃圾收集,但除非你真的受到内存限制,否则你不应该到处乱搞或修补你的垃圾收集器。
  4. 确保您了解scoping in Sinatra,以便知道对象何时应该超出范围。然而,仅仅因为对象超出范围并不意味着它们被垃圾回收,只是它们可以被回收。

【讨论】:

  • 经过研究、分析和测试应用程序确实会正确释放内存。因为我使用的是 Legacy 风格的应用程序,所以我确实手动启动了 GC。安全总比后悔好。谢谢!
【解决方案2】:

不确定这是否重要,但我很确定你的 get '/people' 块的最后一行没有被调用,因为你有明确的回报

return people.to_json # this exits the block
people = nil #this never gets called.

【讨论】:

  • 这无关紧要,因为 people 会在请求结束时超出范围,但这肯定是一个值得指出的逻辑错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-31
  • 1970-01-01
  • 2015-10-19
相关资源
最近更新 更多