対象コード > resque_starter.rb#L164
背景
- job queue に resque を使った rails アプリ。load しておくと大体100MBぐらいになるやつ。
- resque worker を並列で動かす際に、CoW を効かせてメモリ節約したいので resque_starter という manager 的なものを作って、アプリケーションコードを前もって読み込んだ上で (
Rails.application.eager_load!) fork するようにしてみた。
問題
- 96M中、64MがPrivateになってしまい、CoWが30%ぐらいしか効いてない。
- unicorn worker は 86% ぐらい効いているのに> <
- もっと効いて欲しい or 妥当なのかどうかを知りたい
しばらく置いたあとの /proc/PID/smaps の [heap]
7f63aa811000-7f63b06cf000 rw-p 00000000 00:00 0 [heap]
Size: 97016 kB
Rss: 96700 kB
Pss: 80302 kB
Shared_Clean: 0 kB
Shared_Dirty: 32796 kB
Private_Clean: 0 kB
Private_Dirty: 63904 kB
Referenced: 96700 kB
Anonymous: 96700 kB
AnonHugePages: 0 kB
Swap: 0 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
どこで Private が増えたのか調べるために binding.pry で止めて step 実行しつつ、smaps を見てみる。
fork 直後ですぐに 12M が private になる ...
7fd83b98b000-7fd841b2f000 rw-p 00000000 00:00 0 [heap]
Size: 99984 kB
Rss: 99648 kB
Pss: 55852 kB
Shared_Clean: 0 kB
Shared_Dirty: 87592 kB
Private_Clean: 0 kB
Private_Dirty: 12056 kB
Referenced: 27928 kB
Anonymous: 99648 kB
AnonHugePages: 0 kB
Swap: 0 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
@self_read.close および @self_write.close 直後。4M も Private になるの ...
7fd83b98b000-7fd841b2f000 rw-p 00000000 00:00 0 [heap]
Size: 99984 kB
Rss: 99648 kB
Pss: 58308 kB
Shared_Clean: 0 kB
Shared_Dirty: 82680 kB
Private_Clean: 0 kB
Private_Dirty: 16968 kB
Referenced: 33096 kB
Anonymous: 99648 kB
AnonHugePages: 0 kB
Swap: 0 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
worker.work 直後。45M ....
7fd83b98b000-7fd841b2f000 rw-p 00000000 00:00 0 [heap]
Size: 99984 kB
Rss: 99648 kB
Pss: 72384 kB
Shared_Clean: 0 kB
Shared_Dirty: 54528 kB
Private_Clean: 0 kB
Private_Dirty: 45120 kB
Referenced: 59212 kB
Anonymous: 99648 kB
AnonHugePages: 0 kB
Swap: 0 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
あれ、ひょっとしてプロセス(1)から fork (2)してさらに fork (3)してると、Private_Dirty は親のもの(2) を引き継ぐ?
※ (2) が resque_starter で (3) が resque_worker