如何解决Ruby中垃圾收集导致的零星崩溃问题
我有一个基于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会被许多物体绊倒,或者存在泄漏内存的错误.在任何一种情况下,使用 接下来,考虑调整garbage collection parameters.这不会帮助您找到错误的原因,但它可以防止它发生.可以在in this post找到对GC.stat输出的相当广泛的调查以及可以调整的环境变量的含义. 它也可以帮助到manually initiate GC.如果处理中的一点有点放慢不会受到影响,请收集垃圾以使堆保持在可管理的水平.显然,这可能掩盖了潜在的问题,并减慢了您的应用程序.所以要谨慎使用.但是,如果找不到错误的根本原因,最好避免崩溃或者使崩溃更具可重复性. 最后,您可以尝试使用alternative (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |