加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

如何解决Ruby中垃圾收集导致的零星崩溃问题

发布时间:2020-12-17 01:57:23 所属栏目:百科 来源:网络整理
导读:我有一个基于Grape v0.19.2的 Ruby v2.3.4应用程序. 最近,在我们上次部署之后,我们注意到系统关闭,我们的神v0.13.7进程监视器再次启动它.在查看了崩溃日志后,我们每周看到20-30次崩溃. 以下是一些示例崩溃报告: /.rvm/gems/ruby-2.3.4/gems/bson-4.2.1/lib/
我有一个基于Grape v0.19.2的 Ruby v2.3.4应用程序.

最近,在我们上次部署之后,我们注意到系统关闭,我们的神v0.13.7进程监视器再次启动它.在查看了崩溃日志后,我们每周看到20-30次崩溃.

以下是一些示例崩溃报告:

/.rvm/gems/ruby-2.3.4/gems/bson-4.2.1/lib/bson/hash.rb:80: [BUG] rb_gc_mark(): 0x007fa2f4fb33f0 is T_NONE
/.rvm/gems/ruby-2.3.4/gems/mongo-2.4.1/lib/mongo/socket.rb:176: [BUG] rb_gc_mark(): 0x007f990c383360 is T_NONE
/.rvm/gems/ruby-2.3.4/gems/activesupport-5.1.1/lib/active_support/callbacks.rb:102: [BUG] rb_gc_mark(): 0x007ffbeb9e3880 is T_NONE

这些崩溃似乎是随机发生的,可以相隔5-7天,也可以在一小时内完成.崩溃日志中的堆栈跟踪不是很有帮助,基本上显示了我们正在运行的所有内容.

目前我们的策略是回滚整个代码库并查看所有进行的更改,但它们非常多. 30-40更新的宝石的依赖性也发生了变化.由于崩溃似乎是随机的,因此很难测试对代码或gem的更改是否已修复该问题.

此问题似乎与垃圾收集相关,因此我尝试在调试模式下使用GC来查看是否可以帮助我们创建可重现的案例,但是应用程序启动和运行的时间会长几个数量级,因此策略不可行.

什么是强制崩溃的好策略,以便我们可以缩小问题是来自我们的代码更新还是依赖的gem?

解决方法

我没有在Ruby中调试过这种问题,但我可以给出一些一般性的建议.正如您所发现的,Ruby的 mark and sweep garbage collection可能无法预测.在最好的时候调试内存问题可能会非常令人沮丧,但是当你无法可靠地重现bug时,调试起来就更难了.幸运的是,有一些事情要深入研究这个问题.

首先,垃圾收集错误通常与大量内存分配相关联. GC会被许多物体绊倒,或者存在泄漏内存的错误.在任何一种情况下,使用GC.stat收集有关处理中各个点的内存状态的信息.如果您看到内存分配不断增长,您可以开始缩小内存分析器(如this one)可能出现的问题的范围.如果您可以找到内存被吃掉的地方,那么您就有了一席之地.也许避免引入导致问题的宝石或改变存储数据的方式.

接下来,考虑调整garbage collection parameters.这不会帮助您找到错误的原因,但它可以防止它发生.可以在in this post找到对GC.stat输出的相当广泛的调查以及可以调整的环境变量的含义.

它也可以帮助到manually initiate GC.如果处理中的一点有点放慢不会受到影响,请收集垃圾以使堆保持在可管理的水平.显然,这可能掩盖了潜在的问题,并减慢了您的应用程序.所以要谨慎使用.但是,如果找不到错误的根本原因,最好避免崩溃或者使崩溃更具可重复性.

最后,您可以尝试使用alternative malloc implementation.如果您不介意从源代码构建Ruby,则可以很容易地更换C编译器提供的默认malloc并尝试其他方法.同样,它可能会掩盖潜在的问题.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读