SBT子项目出现内存溢出问题

7
我们使用SBT 0.13和Java 8 JVM在CircleCI上构建一个带有多个子项目的Play应用程序。我们偶尔会在CircleCI上遇到内存不足的问题,因为它超出了4 GB的内存使用限制,导致构建失败。
昨天,我向我们的构建项目添加了一个新的子项目,现在几乎所有的构建都因为内存不足而失败。看起来添加子项目也增加了构建所使用的内存量。
我尝试了几种方法来减少内存负荷:
- 在`circle.yml`中添加`_JAVA_OPTIONS: "-Xms512m -Xmx2048"`,如CircleCI文档页面所述。(我从日志中注意到JVM确实接受了这个设置。) - 在SBT调用中添加`-mem`参数。 - 在SBT文件顶部添加`concurrentRestrictions in Global += Tags.limit(Tags.Test, 1)`,以确保至少不会一次性使用所有内存。
所有这些措施似乎都有所帮助,但我还没有找到这个问题的最终解决方案。
除此之外,我还能做什么来控制SBT的内存使用?
注:“我们的项目有5个子项目,大约有14000行Scala代码(并且还有21000行Java代码是我们‘继承’来的)。通常(但不总是),内存不足会在使用FindBugs执行静态分析时发生:我们与FindSecurityBugs插件一起使用它来查找安全问题。”

@rumoku 很好的问题;我编辑了我的问题来回答它们。 - jqno
你在不同的阶段遇到了问题,与这个其他问题不同,但它仍然可能对你有所帮助:https://dev59.com/P3LYa4cB1Zd3GeqPV03k?rq=1 - 2rs2ts
@2rs2ts 感谢您的建议。但是,我们正在使用Java 8 JVM,因此更改PermGen设置对我们没有帮助。另外,为单个JVM分配额外的JVM将有助于解决PermGen问题,但对于多个JVM的集体内存使用情况,恐怕无济于事。 - jqno
这是PermGen问题吗?你使用的Java版本是什么? - Edmondo
@Edmondo1984 不是,它是Java 8 JVM。不过你说得对,我已经更新了我的问题。 - jqno
显示剩余3条评论
1个回答

1
这里有两个混淆在一起的问题:
  1. Circle CI无法获取内存限制的值

  2. SBT使用过多的内存

第一个问题需要查看CircleCI文档/示例进行解决。为了调查为什么使用了如此多的内存,您可以在本地运行带有低于4g(例如2g)内存限制的sbt。您将发现自己处于以下两种情况之一:
  1. 你的测试使用了太多内存,可能是由于内存泄漏引起的。你的JVM因为java.lang.OutOfMemoryError: GC overhead limit exceeded而退出。你应该在本地使用分析器运行构建,查看是什么导致了你的问题(数据库连接未关闭?)

  2. 由于SBT能够动态重新加载类,你的测试使用了太多内存:在SBT中,完全可以在同一个JVM中重新加载类(例如,您可以启动控制台,加载类,编辑文件,重新编译并重新启动控制台和重新加载类)。如Oracle文档所述,Java 8中没有最大元空间的限制,因此您应该设置一个,使您的堆+元空间<4gb。请参见https://blogs.oracle.com/poonam/entry/about_g1_garbage_collector_permanent


  1. 我已经在本地完成了我在问题中列出的所有事情。我将所有东西都限制在1.5G,但每次我看到内存高达2.5G。我使用终端中的“top”进行了简单的性能分析,尽管我知道那不是正确的方法。
  2. 我不知道这个元空间的事情。我一定会尝试一下!虽然我只是运行sbt test并在运行时让文件保持不变。
- jqno
JVM 的占用不仅包括堆,还包括 MetaSpace。通过将内存限制为 2g 堆,您的测试是否成功? - Edmondo
我还没有尝试显式设置元空间(虽然据我所知,SBT的-mem开关应该会处理这个问题)。我今天稍后会尝试设置-XX:MetaspaceSize并回报结果。 - jqno
“MetaspaceSize”设置并没有完全解决问题,但是您的评论引导了我正确的方向。事实证明,我的设置确实限制了SBT的内存使用,只是在“top”中显示为使用更多。因此,如果我将其限制在2048M,那么“top”将显示2500M或更多。如果我将其限制在1024M,那么“top”将会超过1700M。 (在这两种情况下,我都将元空间设置为512M。)我还不太理解它,但我会接受它。由于您促使我尝试了一些有帮助的新事物,所以我会给您奖励。 - jqno
现在你应该附加一个分析器,比如JRockit,以了解是什么在使用这么多内存。 - Edmondo
确实。不过我会在度假回来后再去完成这个练习。(我只是进行了足够的研究,看看是否可以颁发悬赏,否则它将过期 :).) - jqno

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