在非常复杂的Ruby应用程序中查找内存泄漏

时间:2011-09-14 16:22:31

标签: ruby memory-leaks

大家好!

使用Ruby并编写一些代码很高兴。但是在本周的过去,我注意到我们的应用程序存在一些问题。内存使用量正在增长,如O(x * 3)函数。

我们的应用程序非常复杂,它基于EventMachine和其他外部库。更重要的是,它使用Ruby 1.8.7-p382

在FreeBSD的amd64位版本下运行

我试图自己研究如何在我们的应用中发现内存泄漏。 我发现了很多工具和库,但它们在FreeBSD'64bit下不起作用,我不知道如何在巨大的ruby应用程序中找到漏洞。没关系,如果您的文件只有200-300行代码,但是这里有大约30个文件,平均代码为200-300行。

我只是意识到,我需要太多的时间来发现这些漏洞,做一些愚蠢的行为:相信/研究/假设这部分代码的某些部分可能实际上正在泄漏并包装一些跟踪代码,比如使用ruby-prof宝石技术。但它的速度非常缓慢,因为我说我们的代码太多了。

所以,我的问题是如何在非常复杂的Ruby应用程序中找到内存泄漏而不是将所有生命投入到这项工作中?

提前谢谢

3 个答案:

答案 0 :(得分:2)

在Linux机器上运行你的应用程序有多难?如果你在那里没有相同的内存问题,它可能是你的ruby运行时特有的东西。如果您遇到同样的问题,可以使用仅限linux的所有工具和库。

另一种选择 - 你可以用一些内存跟踪代码包装单元测试吗?大多数单元测试框架可以在每次测试之前/之后轻松添加一些代码。或者你可以运行每次测试10万次,看看内存是否失控?如果确实如此,你知道在该测试中发生的事情会导致泄漏,你可以继续隔离问题。

答案 1 :(得分:2)

要尝试的一件事,即使它可以大规模降低性能,也是通过每隔一段时间调用GC.start来手动触发垃圾收集器。多久一次是主观的,因为运行得越多,应用程序就越慢,运行得越少,内存占用就越大。

无论出于何种原因,垃圾收集器可能会不时休假,如果进行一些繁重的处理,可能不想干扰。因此,您可能需要手动打电话才能取走垃圾。

避免创建垃圾的一​​种方法是更有效地使用内存。当数组执行任务时不要创建哈希,当单个字符串就足够时不要创建数组,依此类推。在您开始随机攻击之前,对您的应用程序进行概要分析以查看哪些对象混乱堆积非常重要。

如果可以,请尝试使用1.9.2,它在内存管理方面取得了显着进步。如果您需要1.8.7兼容性,Ruby Enterprise Edition也是一个选项,因为它本质上是该版本的更好的垃圾收集器。

答案 2 :(得分:1)

您是否尝试使用ObjectSpace.each_object计算您拥有的对象数量?虽然您打算使用小批量,但也许您只有更多的对象。

count = ObjectSpace.each_object() {}
# => 7216