2016-12-28 46 views
7

我們在CircleCI上使用SBT 0.13和Java 8 JVM來構建包含多個子項目的Play應用程序。我們偶爾會在CircleCI上發現內存不足的問題,因爲它超過了4 GB的內存使用量,因此中止了構建。SBT內存不足與子項目

昨天,我在我們的版本中添加了一個新的子項目,並且幾乎所有的版本現在在內存不足問題上都失敗了。看起來添加子項目也增加了用於構建的內存量。

我已經試過幾件事情,以減少我們的記憶負荷:

  • 添加_JAVA_OPTIONS: "-Xms512m -Xmx2048"circle.yml作爲CircleCI's documentation pages描述。 (我從日誌中注意到JVM確實在這個設置上有所提升。)
  • 將一個-mem參數添加到SBT調用中。
  • concurrentRestrictions in Global += Tags.limit(Tags.Test, 1)添加到SBT文件的頂部,以確保至少內存不會一次全部使用。

所有這些措施似乎都有所幫助,但我還沒有找到這個問題的確切解決方案。

我還能做些什麼來控制SBT的內存使用情況?

編輯:我們的項目有5個子項目,約有14000行Scala代碼(以及我們繼承的21000行Java代碼)。在使用FindBugs執行靜態分析時,通常(但不總是)發生內存不足:我們使用它與FindSecurityBugs插件一起查找安全問題。

+0

您的項目有多大?你有多少行代碼?你什麼時候編譯OOM?打包?測試階段? – Rumoku

+0

@rumoku好問題;我編輯了我的問題來回答他們。 – jqno

+0

您看到的問題與其他問題不同,但它可以幫助您:http://stackoverflow.com/questions/16640823/sbt-runs-out-of-memory?rq=1 – 2rs2ts

回答

1

有兩個問題在這裏,越來越混合:

  1. 圈CI未使用的存儲器過量的內存限制拾取值

  2. SBT

第一問題必須通過查看CircleCI文檔/示例來解決。爲了調查爲什麼你使用這麼多的記憶,你可以在本地運行你的sbt,其內存限制低於4g(即2g)。你會發現自己在這兩種情況之一:

  1. 你的測試真的使用太多的內存,可能是因爲內存泄漏。您的JVM由於java.lang.OutOfMemoryError: GC overhead limit exceeded而退出。你應該用profiler在本地運行這個版本,看看是什麼導致你的問題(數據庫連接沒有關閉?)

  2. 由於SBT能夠動態地重載類,你的測試使用了太多的內存:在SBT中,在同一個JVM中完全重新加載類(例如,您可以啓動控制檯,加載類,編輯文件,重新編譯並重新啓動控制檯並重新加載類)。如Oracle文檔中所述,Java 8中的Maximum MetaSpace沒有限制,您應該設置一個,以便您的堆+元代空間< 4GB。請參閱https://blogs.oracle.com/poonam/entry/about_g1_garbage_collector_permanent

+0

1.我已經完成了本地問題中列出的所有事情。我已經將一切限制在1,5G,但每次看到內存高達2,5G。儘管我知道這是不正確的做法,但我在終端上使用'top'做了一個可憐的人的分析。 2.我不知道這個metaspace的東西。我一定會嘗試一下!儘管我只是運行'sbt test',並在運行時單獨保留文件。 – jqno

+0

JVM佔用不僅僅是堆,它也包含MetaSpace。將內存限制爲2g堆,您的測試是否成功? – Edmondo1984

+0

我還沒有嘗試明確地設置元空間(儘管,據我所知,SBT的'-mem'開關應該照顧到這一點)。我會在今天晚些時候嘗試設置'-XX:MetaspaceSize'並回報。 – jqno