問題は、cgi.d の無害に見える makeChunk プログラムにあると思われます。不要な割り当てを避けるために変更したところ、ここで実行した簡単なテストではるかにうまくいったので、新しいバージョンを試してみれば、運が良くなることを願っています.
cgi.d の新しいバージョンは、次の場所から入手できます。
https://github.com/adamdruppe/misc-stuff-included-D-programming-language-web-stuff
これで問題が解決しない場合は、コミットを見て、修正内容を確認することをお勧めします
。コミット/848566eaf76ae708ccf0109fbb369e2c883f5379
byte[] を作成し、それに必要な部分 (長さ、データ、ターミネーター) を追加することで機能する、makeChunk と呼ばれる無害に見える関数がありました。なぜこれを行うのか知りたい場合は、Web で http 1.1 仕様を検索し、「Transfer-Encoding: chunked」ヘッダーのセクションを調べてください。(embedded_httpd 以外のモードで cgi.d を使用した場合、この関数は呼び出されません。cgi.fastcgi、および scgi の場合、Apache/IIS/nginx/サーバーはこのような詳細を処理するため、cgi.d は単にパスします。しかし、embedded_httpd では、プロトコルの通信中の詳細に注意を払う必要があります.私は実際にはプレーンな古い CGI モードで最も頻繁に使用するので、このようなバグは私をすり抜けてしまう可能性があります!)
そもそもなぜ今のやり方ではなく、このようにしたのですか?ええと、覚えていません。シンク デリゲートを追加したのは、その関数が作成されるまでではなかったと思います。小さなケースで機能するので、大したことではありません。
とにかく、D の ~= 演算子は、少なくとも空の配列で、ガベージ コレクターを介して新しいメモリを割り当てます。ファイルが非常に大きい場合 (私のテストでは、100 MB のランダム データを使用しただけです)、この参照によってアドレス空間が大量に消費される可能性があります。
32 ビットでは、アドレス空間は 4 GB です。もちろん、100 MB はその約 1/40 です。D ガベージ コレクタは保守的です。つまり、使用可能なすべてのスペースをスキャンし、別の方法で確実に認識されない限り、検出した数値はポインターである可能性があると想定します。スタック上にあるランダムなデータはすべてポインターであると想定されるため、その巨大な配列を指している場合、実際にまだ使用されている場合に備えて、gc はそれを解放しません。
これは、小さな配列 (および 64 ビットの大きな配列、実際には大きなデータを指している乱数のオッズは事実上ゼロであるため) では非常にうまく機能しますが、ここではオッズはわずか 1/40 です。そのため、gc がスキャンするデータに多かれ少なかれ乱数が 100 個ある場合、まったくランダムなオッズによって、その巨大な配列を誤ってメモリに固定する可能性が高くなります。
それがそもそもこれが問題である理由であり、私の最初のコメントの1つが「バイトの削除」を試みて、それを実行から除外することだった理由です。しかし、トリッキーな部分は、cgi.d がうっかりコピーを作成してしまい、誰にも言わなかったということです....だからあなたは完全に勤勉で、それでもメモリリークを起こす可能性があります。
したがって、解決策は、配列の追加操作を避けることでした。代わりに、ピースをソケットに直接書き込むだけになりました。