虽然有内存消耗到一定程度之后自动重启的工具,但还是治标不治本吧。
因为有一些数据量很大,并且较为复杂的 api,只要一访问,内存就上去十几 M,而且 res end 之后,内存压根不施放,直到占满重启
坛子里也搜了很多资料,帮助不大,也排除了有内存泄漏的 gem(如果是内存泄漏的话,表现应该是内存增增减减,而不是一路往上只增不减吧?)
问一下有没有人遇到过类似的问题,是如何解决的?
主要泄露部分的代码 @huacnlee 能否帮 review 下
get 'records' do
view = View.find(params[:view_id])
# 省略鉴权部分
# view.records_list_ids 是一个大数组,直接从 redis 中拿出来的,可能高达2万个字段,paginate_ids代码见下方
records_ids = paginate_ids(view.records_list_ids)
records = Record.where(id: { '$in' => records_ids })
# where in 之后的排序,O(n)算法,应该没问题
records = view.sort_records(records)
present records, with API::Entities::Records
end
def paginate_ids(collection)
return [] if collection.blank?
base_record_index = collection.find_index(params[:from])
if params[:direction] == 'forward'
res = collection.slice(base_record_index, params[:limit])
else
offset = base_record_index - params[:limit]
res = if offset >= 0
collection.slice(offset, params[:limit] + 1)
else
collection.slice(0, base_record_index + 1)
end
end
end
嗯,我的也是用 rails+puma,我遇到的情况是:之前服务器运行内存是 1G 的,跑网站 (http://sxysxy.org) top 命令看内存基本占满。之后升级内存到 2G,过段时间再用 top 看内存占用又几乎满了。 但是短时间看并没有什么问题,连续运行十几天内存都是那种状态,但是网站很好的运行....qwq
#11 楼 @ruby_sky #8 楼 @tzwm 想彻底解决问题
#10 楼 @MrPasserby 我也这么想 present records, with API::Entities::Records 改成 present [], with API::Entities::Records 内存就增长很慢,而且有回收的迹象,但是也看不出什么,补充一下这块的代码:
module API
module Entities
class Records < Base
expose :comments_count
expose :followers, using: API::Entities::Users
expose :cells, unless: :without_cells do |instance, options|
self.cells(options[:columns] || self.columns)
end
def columns
object.sheet.columns
end
def cells(columns)
{}.tap do |cells_hash|
raw_cells = object.cells
columns.each do |column|
value = raw_cells[column.column_id]
case column.type
when 'date'
value = value.try(:iso8601, 3)
when 'metadata'
meta_type = column.config['type']
value = object.try(meta_type)
if %w(created_at updated_at).include?(meta_type)
value = value.try(:iso8601, 3)
end
end
cells_hash[column.column_id] = value
end
end
end
end
end
end
#7 楼 @jicheng1014 唉,超级厉害,如果一直访问几万条数据的 api,分分钟钟跑满了,现在换成 4G 要稍稍好一些,但是内存还是一直上涨
先用 monit 顶一阵。开多个 puma 的进程,定期重启内存超标的进程。ruby 这东西的内存经常会产生这种问题。自杀是避免不了的,memcached 的缓存要加上。
看看 API::Entities::Users 里面有没有引用到 API::Entities::Records. 如果这边声明了 expose :followers
那边又声明一个 expose :records, using: API::Entities::Records
是有可能导致内存问题。