如何为MoarVM提供更多内存?(Perl6相关)

6

我需要对大约200万行数据进行数据分析,每行数据大约250字节。所以总共大约500兆字节的数据。我正在运行具有4G内存的Virtualbox Linux上的最新Rakudo版本。

大约8个小时后,由于内存不足,我得到了MoarVM恐慌。我该如何为MoarVM提供更多的内存?不幸的是,我不能将这200万行数据分成块并先写入文件,因为数据分析的一部分需要整个2M行。


值得追踪内存使用情况,看看代码中是否有某些部分过度使用了内存。 - Brad Gilbert
@lisprogtor 我真的很好奇发生了什么事情... - raiph
嗨raiph,感谢您的帮助。我正在阅读有关分析器的内容,但还不熟练。为了节省时间,我最终做的是首先隔离需要从所有2M行中获取一些信息的一个数据数组;然后将这2M行写入磁盘并从文件中读取。目前它正在工作。我仍在阅读分析器。谢谢! - lisprogtor
2个回答

6
MoarVM没有自己的内存上限(不像JVM)。相反,它只有在从操作系统请求内存并且被拒绝时才会给出“内存不足”或“内存分配失败”的错误。这可能是由于配置的内存限制,也可能是因为可用的RAM/交换空间不足以满足所需求(如果您尚未配置限制,很可能会出现这种情况)。
很难提供关于下一步应该尝试什么的具体建议,因为问题中缺少程序的详细信息,但以下几点可能有所帮助:
- 如果您正在将文件中的数据处理为其他数据结构,并且可以这样做,请懒惰读取文件(例如,for $fh.lines { ... } 只需要在内存中保留当前正在处理的行的Str,而 my @lines = $fh.lines; for @lines { } 将保留所有的Str对象)。 - 文件中的数据是否为ASCII或Latin-1?如果是,请在打开文件时传递:enc<ascii>或类似选项。这可能会导致较小的内存表示。 - 如果需要保留大量的整数、数字或字符串数组,请考虑使用本机类型的数组。例如,如果您有my int8 @a并存储了一百万个元素,则需要1 MB的内存;如果使用my @a,它们将全部成为一个包含在Scalar容器中的封装对象,在64位机器上可能会占用超过70MB。如果您有一个要创建许多实例的对象,并且可能能够使某些属性本地化,则类似的规则也适用。

非常感谢Jonathan Worthington!我有这2M行的数组和哈希表。可能需要修改一些代码。谢谢。 - lisprogtor
如果你所指的“需要修改的代码”是指你的代码,能正常工作的那种代码,我建议你退一步再想一想。是的,可能有少量的情况下你需要更改你的代码。但更大的可能性是,“没有足够的可用RAM /交换空间来满足所提出的请求”,这很可能是“如果你没有配置限制”的情况。你是否已经配置了限制?这将是要做的jnthn建议中的第一件事。如果你不知道如何做,请务必询问。除非必须,否则不要更改你的代码!!!如果你知道自己已经使用了最大的RAM设置,请阅读我在我的答案中的大声评论。 :) - raiph

4
我建议您分几步解决问题:
  • 如果尚未准备好,请准备两个小的示例文件。保持它们非常小。我建议一个2000行长的文件和一个20000行长的文件。如果您已经有了大约那么长的一些示例文件,则可以使用这些文件。对于每个文件运行您的程序,记录每个文件所需的时间和内存使用情况。

  • 更新您的问题并附上有关持续时间和RAM使用情况的注释;如果可能,请附上源代码链接和示例文件链接。

  • 再次运行两个示例文件,但使用如此处所述的性能分析器。查看需要查看的内容并更新您的问题。

如果您不知道如何执行以上任何操作,请在评论中询问。

如果以上所有操作都相当容易,请针对100,000行的文件重复以上步骤。

然后我们应该有足够的数据来为您提供更好的指导。


非常感谢raiph!我的代码在处理5、100、200K行数据时没有任何错误,但是Moar在处理整个2M行数据时发生了恐慌。我想现在是重新编码的时候了。谢谢! - lisprogtor
我的代码没有BUG,我已经假定了。 "我想现在是重新编码的时候了。" 不要!!!专注于你目前唯一的问题:OOM!盲目更改工作中的代码会产生BUG。相反,你必须收集和共享关于代码内存使用情况的数据。如果你不知道怎么做,你必须提出问题来找到答案。你必须学会如何使用分析器。你只需要更改代码的一小部分。但是哪一部分呢?永远不要猜测!!!相反,你必须一直分析,直到你知道问题所在。只有在那之后,你/我们才会注意jnthn的优秀建议。 - raiph
我的代码可以在5K、100K、200K行数据上无bug运行。当你运行5K文件时,用了多少RAM?100K的文件呢?请更新你的回答来说明一下(还有,每个文件运行的时间是多久)。如果你首先关注jnthn的交换空间配置提示和/或收集并分享你现有代码的运行数据(包括学习如何使用内置分析器,如我在回答中所解释的),那么你将会更加快乐,获得更多知识,并且更快地解决问题;而如果你只是看着代码瞎折腾,那就没那么有意思了。 - raiph
谢谢你,raiph!!!Profiler对我来说是全新的,我现在开始阅读文档。让我试试它。谢谢!!! - lisprogtor
听到这个消息很好,但之前的步骤怎么样了呢?我认为你按顺序应该做以下几件事情:1)了解你的程序总共使用了多少内存来运行5000次和100000次;2)让我们知道,并且也告诉我们时间;3)配置VirtualBox以提高你的交换空间(这会“增加”到4GB中);4)学习使用性能分析器;5)让我们知道在性能分析器下,你看到的关于5K和100K运行的一些基本统计数据。 - raiph

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接