2016-04-18 8 views
3

Windows(バージョン7以上)で64ビットプログラムを実行し、プログラムが物理メモリの100%に近いメモリを割り当てようとすると、システムは停止する。私が時間内にそれをキャッチして、問題のプロセスを抹消しないと、システムが応答しなくなり、ハードリブートが必要になります。明らかに、プログラムは非常に多くのメモリを割り当てるべきではありませんが、バグが発生する可能性があります。テスト/デバッグの際に私が作業しているコードのバグの影響から他の実行プロセスを保護したい。 (論理的なメモリ制限がシステム全体のメモリチョークからセーフティネットを提供するので、これは32ビットで、問題の少なかった。)64ビットプロセスの過剰なメモリ割り当てによるWindowsフリーズ

だから私は二つの質問があります。

  • をプロセスがそのを制限することができますメモリ消費? Windowsでメモリ制限を設定できるシステムコールがあるので、システム全体がクラッシュするのではなく、制限を超えた割り当てが失敗する可能性がありますか?

  • また、システム全体のプロセスごとのメモリ制限を設定する方法や、特定のアプリケーションの制限を設定する方法はありますか?

ここに私のコンピュータがフリーズするサンプルコードがあります。それは、x86_amd64構成のVisual Studio 10.0でコンパイルされ、Windows 8.1で16GB RAMのラップトップで実行しました。 32 GBのメモリを割り当てようとします。 自己責任で実行してください。

int main(void) 
{ 
    const static int csNumArrays=10, csArraySize=800000000; 
    int i, j, **p; 

    p=new int*[csNumArrays]; 
    for (i=0; i<csNumArrays; ++i) 
    { 
     p[i]=new int[csArraySize]; 
     for (j=0; j<csArraySize; ++j) 
      p[i][j]=j; 
    } 
    return 0; 
} 
+0

https://blogs.technet.microsoft.com/clinth/2012/10/11/can-a-process-be-limited-on-how-much-physical-memory-it-uses/ –

+0

@HansPassantありがとうございますが、これは私が必要とするものではありません。ちょうど明確にするために:私はプロセスの物理的なメモリの制限(別名 "ワーキングセット")を操作しようとしていない、私はプロセスの仮想メモリのサイズを制限しようとしている。私は、ソースコードが利用可能であるとき(例えば、システムコールを通して)、またはソースコードが利用できないときに管理ツールを介して外部からそれを行うことを試みている。 – user3204459

+0

@HarryJohnstonご返信ありがとうございます。あなたはそれがシステム全体を崩壊させるべきではないとあなたはあなた自身でそれを試しましたか?私は一貫して、3つの異なる機会に、異なるバージョンのWindowsを持つ異なるマシン上で、まったく異なる状況で異なるソフトウェアを使用していました。それはまた、Linuxで私に起こったが、私はそこでそれを解決する方法を知っている。私はこれが単なる偶然のものだとはほとんど信じていません。 – user3204459

答えて

4

おそらく最良のオプションは、Windows jobに自分自身を入れてProcessMemoryLimitオプションを適用するプロセスです。 (1つのキャッチ:起動スクリプトやスケジュールされたタスクとして実行されているなどの理由で、プロセスがすでにジョブ内にある場合は、この方法は機能しません)同じ手法を使用して、あなたは起動します(または既に起動しています)。

また、CreateResourceMemoryNotificationを使用するスレッドをスピンアップして、物理メモリの状態が低いことを検出してプロセスを終了させることもできます。しかし、これは偽陽性の対象になることがあります。

3

ハリー・ジョンストンの有益な答えに基づいて、プログラムのメモリ割り当てに制限を課すために、プログラムの先頭に追加できるコードをまとめました。物理メモリサイズの係数。

ULONGLONG aMemSize; 
HANDLE aJob=::CreateJobObject(NULL, NULL); 
JOBOBJECT_EXTENDED_LIMIT_INFORMATION aLimit; 

    // Get physical memory and set process memory limit to 75% of physical memory 
GetPhysicallyInstalledSystemMemory(&aMemSize); 
aMemSize*=size_t(768);      // convert kb to bytes and apply 75% factor 
memset(&aLimit, 0, sizeof(aLimit)); 
aLimit.BasicLimitInformation.LimitFlags=JOB_OBJECT_LIMIT_PROCESS_MEMORY; 
aLimit.ProcessMemoryLimit=aLimit.PeakProcessMemoryUsed=aLimit.JobMemoryLimit= 
               aLimit.PeakJobMemoryUsed=aMemSize; 
::SetInformationJobObject(aJob, JobObjectExtendedLimitInformation, &aLimit, sizeof(aLimit)); 
::AssignProcessToJobObject(aJob, ::GetCurrentProcess()); 
関連する問題