2

[规定:我知道这里没有什么是特定于 Delayed::Job 的。但它有助于建立上下文。]

更新

我相信 SQL 查询没有被垃圾收集。我的应用程序生成许多大型 SQL 插入/更新操作(每个 160K 字节,大约每秒 1 个)并通过以下方式将它们发送到 PostgreSQL:

ActiveRecord::Base.connection.execute(my_large_query)

当我执行这些数据库操作时,我的应用程序会无限制地缓慢增长。当我存根数据库操作(但在我的应用程序中执行所有其他功能)时,膨胀停止。

所以:关于为什么会发生这种情况,我如何查明它,或者我如何让它停止的任何想法?

原始问题

我已经延迟了从网络中获取数据并在 PostgreSQL 数据库中创建记录的任务。它们似乎工作正常,但它们从 vmemsize=100M 开始,在十分钟内增加到 vmemsize=500M,并且还在不断增长。当虚拟机用完时,我的 8G RAM MacBook Pro 开始抖动。

我怎样才能找到内存的去向?

在您向我推荐有关该主题的其他 SO 帖子之前:

我在#after(job) 方法中添加了以下内容:

def after(job)
  clss = [Object, String, Array, Hash, ActiveRecord::Base, ActiveRecord::Relation]
  clss.each {|cls| object_report(cls, " pre-gc")}
  ObjectSpace.each_object(ActiveRecord::Relation).each(&:reset)
  GC.start
  clss.each {|cls| object_report(cls, "post-gc")}
end

def object_report(cls, msg)
  log(sprintf("%s: %9d %s", msg, ObjectSpace.each_object(cls).count, cls))
end

它报告基本类的使用情况,显式重置 ActiveRecord::Relation 对象(由this SO post建议),显式执行GC(如this SO post建议),并报告有多少对象/字符串/数组/哈希等有(如this SO post所建议的)。就其价值而言,这些课程都没有显着增长。(我应该看其他类吗?但这不会反映在对象的数量上吗?)

我不能使用memprof,因为我运行的是 Ruby 1.9。

如果我在 Linux 上运行,我会考虑其他工具,但我在 OS X 上。

4

1 回答 1

1

更新

恐怕这都是一条红鲱鱼:运行足够长的时间,每个 ruby​​ 作业都会增长到大约 1.2GB 的 vmsize(是的,那么大,但按照今天的标准来说并不大),然后缩小到 850MB,并在此后这两个值没有继续变大。

我真正的问题是,我试图在具有 8GB RAM 的机器上运行四个以上这样的进程,这会填满所有可用的 RAM,然后进入交换缺氧状态。只运行四个进程几乎会填满可用内存,因此系统不会开始交换。

更新 2

不,仍然是一个问题——我没有让工作运行足够长的时间:工作不断增长(尽管速度很慢)。即使只运行两个外部作业最终也会消耗所有 VM,并且我的机器开始抖动。

我尝试运行生产模式(认为开发模式可能会缓存没有被释放的东西),但它没有产生任何明显的差异。

于 2012-07-12T22:26:06.873 回答