ところが、このプログラムmallocの結果を全然チェックしておらず、catchもしていません。またプログラムを使っている人たちもLinuxに関しては素人ということで、何が悪いのか理解させるのに一苦労。試しにちょっとサンプルプログラムを作って見ました。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define MALLOC_SIZE 100000
int main()
{
int i,j;
int *pt;
for (i=0; i<10000; i++) {
pt = (int *)calloc( MALLOC_SIZE, sizeof(int));
if (pt == NULL) {
printf("## calloc error!! i= %d ##\n", i);
exit(0);
}
for (j=0; j<MALLOC_SIZE; j++) {
pt[j] = i;
}
}
}
取得したメモリに値を書き込んでいるのは、こうして実際に何か使わないと、それまでは本当にメモリの取得につながらないからです。(最初、これで苦労しました)
さてこれで実行してみるとerrorが出たときの、iの値は8,017、あれ?毎回400KB近くのメモリを取得しているはずなのに、これだと3.2GBのメモリを取得したことになっちゃうぞ?確か、Linuxだと1プロセスの最大サイズは2GB弱で、そのうちStackが1GB、Heapが700MBくらいだったはず。おおすぎます。
そこでValgrindでチェックしてみると、i=6,910 2.764GBのheap要求がされたとのこと。(計算が合う)再度、ぐぐりましたが、どうも1プロセスでのサイズ制限はなくなり、4GBのどの空間をKernel用、Stack用、Heap用に用途わけするようになったみたいです。
マシンを占有できれば大きなプログラムを動かせますが、動作解析が更にやっかいになったようです。
0 件のコメント:
コメントを投稿