nashcft's blog

時々何か書く。

CircleCI to GitHub Actions 移行日記

追記 (2020-06-13)

この件その後ログを精査してみたら、メモリの問題じゃなくて実行しているテストの1つにあった非同期処理の実装がまずくて処理が迷子になったまま帰ってこないのが原因だった。

追記終わり

職場の Android アプリのCIに CircleCI を使っていたのだけど、古いプランのままでコンテナのRAMが4GBの medium しか使えないのと、アプリの規模が大きくなりつつあるために色々対策をしてもOOMで落ちることがままあり、幾らかお話をした結果として現状簡素なCIしか無いし欲しいのは十分なRAMくらいなので CircleCI のプランを現行の performance plan にするくらいなら GitHub Actions の方がコスパが良いということで移行をしている。

先にビルドがより不安定な project から移行をして、そちらは問題なく移行できたのだけど、最も安定していた project を移行した際に gradle task の実行中に特に中断されるでもなく応答が返ってこなくなるという挙動に遭遇した。よくあるCI用の実行オプションを足しても特に改善される様子がなかったので debug log を出力させてみたところ、 task の実行途中で空き容量を超えた量のメモリ確保の要求がきて、解放しようとしたが殆どもしくは全く空けられず、延々と request が飛んでくるだけといった状況になってることがわかった。

関連する log は以下のような感じ:

[DEBUG] [org.gradle.process.internal.health.memory.DefaultMemoryManager] 728290099 memory requested, 429182976 free
[DEBUG] [org.gradle.workers.internal.WorkerDaemonExpiration] Will attempt to release 694 of memory
[DEBUG] [org.gradle.process.internal.health.memory.DefaultMemoryManager] 728290099 memory requested, 0 released, 429182976 free
[DEBUG] [org.gradle.cache.internal.DefaultFileLockManager] Waiting to acquire shared lock on daemon addresses registry.
[DEBUG] [org.gradle.cache.internal.DefaultFileLockManager] Lock acquired on daemon addresses registry.
[DEBUG] [org.gradle.cache.internal.DefaultFileLockManager] Releasing lock on daemon addresses registry.
[DEBUG] [org.gradle.cache.internal.DefaultFileLockManager] Waiting to acquire shared lock on daemon addresses registry.
[DEBUG] [org.gradle.cache.internal.DefaultFileLockManager] Lock acquired on daemon addresses registry.
[DEBUG] [org.gradle.cache.internal.DefaultFileLockManager] Releasing lock on daemon addresses registry.
[DEBUG] [org.gradle.process.internal.health.memory.DefaultMemoryManager] 728290099 memory requested, 429182976 free
... (以下繰り返し)

Gradle task 実行時のオプションは以下の通り:

 -Dorg.gradle.jvmargs="-Xmx5120m -XX:+HeapDumpOnOutOfMemoryError" -Dorg.gradle.workers.max=2 -Dorg.gradle.daemon=false -Dkotlin.incremental=false

要求されるメモリの量は常に同じなのでずっと同じ要求が繰り返されているんだろうなと思うのだけど、何のために700MB程度確保しようとしているのか、何故できてもほんの少ししか解放できないのかなどわからないことばかりだし、じゃあアプリの規模に対して -Xmx が小さすぎるのかというと見ての通り少なくない、というかむしろかなり多い方だし、大きくなりつつあるとはいえ特別大規模なアプリではないのでカツカツということはないと思っているので、今の自分の gradle に対する知識ではお手上げだなあとなっている。あとこの gradle task が進まなくなる挙動は必ず発生するわけではなく時々完走するので、何か変更を入れたときにたまたまビルドが通るとそこに原因を求めてしまいがちで調査がなかなか進まずもどかしい。