Ruby on rails ActiveRecord未释放内存

Ruby on rails ActiveRecord未释放内存,ruby-on-rails,ruby,memory,memory-leaks,rails-activerecord,Ruby On Rails,Ruby,Memory,Memory Leaks,Rails Activerecord,我有一个导出工作,从MySQL数据库导出大量数据。随着数据的增长,我注意到sidekiq的工作占用了太多的内存。服务器有32GB,导出完成后需要28GB。当我停止sidekiq进程时,内存使用下降到8GB 我已经跟着导游来了 使用MALLOC\u ARENA\u MAX=2防止内存碎片 清除查询缓存ActiveRecord::Base.connection.clear\u query\u cache 我正在使用Ruby 2.6.5p114,并尝试在生产中创建一个新的rails应用程序,并将我

我有一个导出工作,从MySQL数据库导出大量数据。随着数据的增长,我注意到sidekiq的工作占用了太多的内存。服务器有32GB,导出完成后需要28GB。当我停止sidekiq进程时,内存使用下降到8GB

我已经跟着导游来了

  • 使用
    MALLOC\u ARENA\u MAX=2防止内存碎片
  • 清除查询缓存
    ActiveRecord::Base.connection.clear\u query\u cache
我正在使用Ruby 2.6.5p114,并尝试在生产中创建一个新的rails应用程序,并将我的DB用作后端,以此来隔离问题:

gem install rails --version 5.2.4.3
rails new debug -d mysql
我创建了一个空模型,以避免代码中可能导致问题的自定义方法:

class Variant < ApplicationRecord
end
这是输出:

root@6e79d7a97d9c:/usr/src/debug# rails r memory.rb
76.93359375 MB
load_variants...
variant.count: 1000000
2436.3125 MB
GC.start...
2421.046875 MB
load_variants...
variant.count: 1000000
2436.3828125 MB
GC.start...
2436.3984375 MB
  • 它以
    76.93359375 MB开始
  • 加载1百万对象后,内存增加到
    2436.3125 MB
  • 垃圾收集将内存减少到
    2421.046875 MB
    ,但我预计会有更大的下降
  • 有趣的是,第二次运行只会将内存增加到
    2436.3828125 MB
  • 最后一个
    GC.start
    以某种方式将内存稍微增加到
    2436.3984375 MB
  • 我想知道这是怎么回事?ActiveRecord中一定有我不知道的东西,我想了解这一切是如何工作的,以及为什么内存没有被释放


    按照这个逻辑,每次读取数据的请求的内存都应该增加,但我假设在请求-响应周期内使用时会有所不同。

    加载分布在内存中的大型对象(而不是连续内存中的
    字符串
    等对象)在Ruby中,由于Mark&Sweep算法无法将整个内存块返回到操作系统,所以它往往具有这种效果。如果您开始解析大型JSON文件(如10+MB),您将获得类似的效果,因为生成的散列包含大量其他对象,将被放置在多个内存块中,与其他仍然具有活动引用的对象一起,因此Ruby无法释放该块。

    AR bug模板非常适合创建用于测试的自包含代码。
    root@6e79d7a97d9c:/usr/src/debug# rails r memory.rb
    76.93359375 MB
    load_variants...
    variant.count: 1000000
    2436.3125 MB
    GC.start...
    2421.046875 MB
    load_variants...
    variant.count: 1000000
    2436.3828125 MB
    GC.start...
    2436.3984375 MB