Solaris : Minimizing Memory Usage for Creating Application Subprocesses

Oracle の Sun Developer Network に プロセス作成(fork)についての良質な記事があったのでメモ。

Minimizing Memory Usage for Creating Application Subprocesses
By Greg Nakhimovsky, May 2006

Abstract: This article explains how a Solaris OS application with large memory requirements can effectively create a subprocess without unduly running out of memory or creating a deadlock. It also explores a related issue of how application memory is committed in the Solaris OS as opposed to other operating systems such as Linux.


fork 時の物理メモリーコピー問題

fork するとプロセスが親子に分割コピーされる。
初期の Unix(とくに BSD)では fork 時に文字通り親プロセスを何から何までコピーしていた。
シェルで ls を実行するようなケース(fork & exec = spawn)であっても同じ。


  • 親プロセスと同じだけのメモリーが子プロセスでも必要(メモリの大量消費)
  • コピー処理が重い

後年には COW(Copy-On-Write)が実装されるなど、メモリ管理は改善されたが、不要なコピーが行われていることはかわりなく、親プロセスの多くの領域を memory-map しているとパフォーマンスが悪化する

vfork の誕生

これを回避するために1980年代前半に以下の機能を有する vfork が BSD で実装された

  • 親プロセスをコピーせず
  • 親プロセスの物理アドレス空間で実行され
  • 子プロセスが exit するか exec するまで親プロセスがブロックされる 。

vfork は後に Solaris にも移植された。

#”Design and Implementation of the FreeBSD Operating System”  by Marshall Kirk McKusick & George V. Neville-Neil では vfork のことが “architectural blemish” と形容されている。

vfork とマルチスレッド(MT)とデッドロック
vfork すると、親は子が終了するまで待つ。

posix_spawn の登場

Solaris 10 では posix_spawn の導入とともに

  1. 物理メモリ(VM)の重複コピー
  2. デッドロック


posix_spwan 以外の解決策
Out Of Memory にならずに fork する別手段としては、起動時に fork 用の軽量プロセスを作成しておき、fork する際には、その軽量プロセスから fork する方法もある。
Out Of Memory 問題からは開放されるものの、処理が大幅に複雑になってしまう。

Linux の over commit と OOM と OOM Killer
Linux では overcommit(lazy swap allocation) の仕組みがあるため、fork 時に Out Of Memory にならないが以下の メリット/デメリットがある。


  • The fork() call never fails because of the lack of VM.
  • The system memory can be used more flexibly and efficiently, especially when application programs dynamically allocate a lot of memory but don’t fill much of it with data.
  • Memory overcommit can be used for growable (infinitely large) arrays and memory buffers; compare with “Virtual Memory Arrays for Application Software,” reference [4].
  • As a variation of the growable array idea described above, many Fortran programs (especially those created before Fortran-90) don’t use dynamic memory allocation, because earlier Fortran versions did not provide any standard facility for it. Instead, they have very large arrays declared, but only use parts of those arrays. With a non-overcommit system these Fortran programs may not load at all or only load when you waste a lot of disk space for never used swap space.


  • The memory overcommit feature changes the malloc() failure semantics. All those good applications that faithfully check for malloc() returning NULL and producing meaningful error messages and workarounds in that case are doing it for nothing when memory overcommit is used.
  • Arguably, memory overcommit violates the C/C++ standards that require that when malloc() returns a non-NULL pointer, the allocated memory should be available when needed.
  • The memory overcommit feature is global for the entire system. There is no way to use it for some applications but not others, or only for certain memory buffers within a certain application.
  • Most importantly, when a memory overcommit system is out of VM, one or more processes will be killed by the infamous OOM (out-of-memory) process killer due to memory pressure. This may be unacceptable, especially in enterprise-class environments. Random application programs shouldn’t be killed just because somebody else allocated too much VM and filled it with data.

Linux は Kernel 2.6 から overcommit_memory=2 のモードが追加されたため、オーバーコミットしない設定もできるようになった。
しかしデフォルトは 0 の Heuristic overcommit handling モード

Solaris は malloc 時にメモリを確保するので、他のプロセスが確保した領域は使えないし、そもそも確保できなければ malloc は NULL をかえす(malloc の本来の仕様)ので OOM Killer の仕組みは不要。

とはいえ mmap(MAP_NORESERVE) を使えば Linux/Solaris ともに overcommit と同じくメモリの lazy swap allocation が使える。


Do not reserve swap space for this mapping. When swap space is reserved, one has the guarantee that it is possible to modify the mapping. When swap space is not reserved one might get SIGSEGV upon a write if no physical memory is available. See also the discussion of the file /proc/sys/vm/overcommit_memory in proc(5). In kernels before 2.6, this flag only had effect for private writable mappings.

Tagged with: , , ,
Posted in linux

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: