2016-12-04 2 views
0

このコードは、コマンドライン上の入力として数をとり、何回もすることをheapOverflow()関数を呼び出します:Linuxのミント17.1でヒープオーバーフローがシステムをフリーズするのを「許可」するのはなぜですか?

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

void heapOverflow() 
{ 
    unsigned *some_array = malloc(50000); 
} 

int main(int argc, char *argv[]) 
{ 
    unsigned num_calls = atoi(argv[1]); 

    while (num_calls > 0) 
    { 
     heapOverflow(); 
     num_calls--; 
    } 

    return 0; 
} 

が、十分な大きさの入力(私の場合は例えば10000000)でこれを実行していますbashが "Killed"で復帰する前に数分間システムをフリーズさせてから、システムはさらに数分間遅くなります。

なぜOSはプロセスがその程度までメモリを引き継ぐことを許可しますか?スケジューラとメモリマネージャは、あまりにも多くのヒープメモリを要求することが明らかになったときにプロセスを強制終了するべきではありませんか?あるいは、このすべてのメモリを1つのプロセスに与えることが有用な場合があります(つまり、システムの残りの部分、または少なくともX GUIシステムが凍結されている間でも、実際にプロセスが有用な作業をすることができますか?)

+1

'malloc'は、失敗したときに' NULL'を返します。確認してください、それは不可欠です。 –

+2

Linuxカーネルはメモリオーバーコミットを許可しています(プログラムは使用可能なメモリよりも多くのメモリを要求することができ、割り当ては成功しますが、後でメモリが利用できないときにコードがクラッシュします)。あなたの好きな検索エンジンで 'Linux OOM Killer'(メモリ不足のキラー)を検索してください。あなたのコードは実際に割り当てているメモリを使用しません。ポインタのためにスペースを使い果たす必要があるため、メモリ自体ではなく、実行に時間がかかります。メモリを割り当てた後でメモリをゼロにした場合(おそらく 'calloc()'を使用してください)、システムに与える影響は少なく、速くクラッシュします。 –

+0

プロセスが実際に大量のメモリを必要とするときにはどうなると思いますか?とにかくそれは殺されるべきですか? – immibis

答えて

1

OSは、プロセスがそのような程度にメモリを引き継ぐのをなぜ許可しますか?

このように設定されているためです。

Linuxカーネルは、他の機能の中でも、プロセス単位のリソース制限を標準でPOSIX.1-2008でサポートしています。例えば、それらへのコマンドラインアクセスの場合はprlimit、Cライブラリインターフェイスの場合はgetrlimit()/setrlimit()です。

ほとんどのLinuxディストリビューションでは、これらの制限はプラグ可能な認証モジュールpam_limitsで設定されています(limits.conf)。

問題は、これらの制限が非常にタスク固有であることです。システムからシステム、そして実際にはユーザーからユーザーまでさまざまです。ページングを開始するのがシステムのほうを好まず(OPのように遅くなります)、むしろプロセスが失敗することになります。リソースを必要とするプロセスの結果が実際に必要なので、しばらく待っている人もいます。制限を設定するのは、システム管理者の責任です。

私は、現在の設定(特に/proc/meminfo)をチェックし、シングルユーザのデスクトップ/ラップトップマシンのリソース制限を設定するプログラムを簡単に書くことができると思います。しかし、あなただけのようにもヘルパースクリプトを作成することができますので、あなたが256Kに1ギガバイトおよび常駐セットサイズ(実際に使用されるRAMの量)に制限されたアドレス空間を使用してプログラムのいずれかを実行することができます/usr/local/bin/run-limited

#!/bin/sh 
exec prlimit --as=1073741824 --rss=262144 "[email protected]" 

を言いますページ。

関連する問題