記事一覧

WindowsにおけるApacheのスレッドスタックサイズの変更について




目次



Apacheのスレッドスタックサイズについて

ハロー、みなさん。エジソンです。

Apacheのスレッドスタックサイズをご存知でしょうか?

スレッドスタックサイズをそのまま言葉にすると、一つのスレッドに対するスタック領域のサイズが何Byteであるか、ということになります。

メモリの種類について、誤解を恐れずに言い切ると、大抵のプログラムのメモリ確保領域には、スレッド領域とヒープ領域があります。ヒープ領域は長い期間に渡って必要になるデータを確保する領域、一方でスタック領域とは、関数実行時に引き渡された引数や関数内で宣言された変数のデータを確保する領域です。

例えば、C++では、newで生成されたクラスオブジェクトはヒープ領域に、newなしで生成されたクラスオブジェクトはスタック領域に確保される、と言った具合になります。

話は変わりますが、Windowsにおける Apache のデフォルトのマルチプロセッシングモジュール (MPM) は、mpm_winnt となります。

一体何の話をしているのかというと、Apacheを起動すると一つのプロセスが生成され、これにぶら下がる形で子どものスレッドも生成されます(スレッドプール)。そして、Apacheがリクエストを処理する際に、リクエスト一つ一つに子スレッドがあてがわれるという仕組みになります。

Apache MPM winnt
このマルチプロセッシングモジュール (MPM) は Windows NT でのデフォルトになります。 一つの制御用プロセスを用い、これが一つの子プロセスを起動し、 そして子プロセスがリクエストを取り扱うためにスレッドを 起動します。 …

この、子どものスレッド一つ一つにスタック領域のサイズが決まっており、それがスレッドスタックサイズであるという事なのです。

スレッドスタックサイズのデフォルト値は決まっている

スレッドスタックサイズのデフォルト値は決まっています。

デフォルト値はVisual Studioツールの、dumpbin.exeで確認が可能です。apacheの本体の実行ファイルである、httpd.exeに対して以下のように実行してみましょう。

"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\dumpbin.exe" /headers httpd.exe

Microsoft (R) COFF/PE Dumper Version 12.00.30723.0
Copyright (C) Microsoft Corporation.  All rights reserved.

Dump of file httpd.exe

…

           40000 size of stack reserve
            1000 size of stack commit

…

上記の 40000 がスレッドスタックサイズとなります。40000は、16進数なので、10進数に変換して KByte に変換すると、256KByteという値が算出されます。

要するに、スレッドスタックサイズのデフォルト値は256KByteなのでした。

スレッドスタックサイズは変更できる

プログラム実行中にスタックサイズが256KBを超えると、Apacheが異常終了します。

プログラムの特性上、どうしてもスタックサイズが256KBを超えるという場合には、スレッドスタックサイズを変更して対処することができます。

Apacheの設定ファイルである、 httpd-mpm.conf を修正します。

# WinNT MPM
# ThreadsPerChild: constant number of worker threads in the server process
# MaxConnectionsPerChild: maximum number of connections a server process serves

    ThreadStackSize        1.2*1024*1024
    ThreadsPerChild        1000
    MaxConnectionsPerChild    0


上記のように修正する事で、スレッドスタックサイズを 1.2MByte に変更する事ができるでしょう。

変更が本当に有効になっているかが気になるところ。以下のコードで検証することができましたので、紹介します。

<php
ini_set('xdebug.max_nesting_level', 5500);
$contents = 'a';

$GLOBALS['max'] = 2000;
echodo($contents);

function echodo($str) {
    if ($GLOBALS['max'] > 0) {
        $GLOBALS['max'] = $GLOBALS['max'] - 1;
        echo $GLOBALS['max'] . '
'; echodo($str); } else { echo 'OK
'; } }

何をやっているかと言うと、echodoという関数を2000回、ひたすら再帰呼び出しするのです。スレッドスタックサイズがデフォルトの状態で上記を実行すると、Apacheが異常終了します。

スレッドスタックサイズを1.2MByteにした後で実行してみると、正常に動作することが確認できます。

Windows・ApacheでPHPを動作させる場合には、何かとハマることが多いので、皆さんお気をつけください。

関連記事

このエントリーをはてなブックマークに追加

コメント

コメントの投稿

非公開コメント

プロフィール

EZOLABブログへようこそ。
EZOLABは、札幌のソフトウェア会社です。

http://ezolab.co.jp