Unix システムに匿名の mmap が導入されて以来、mmap アドレス空間がデータ セグメント サイズに含まれていないため、RLIMIT_DATA は役に立たないという印象を受けました。特に、glibc の malloc() 実装は、大規模な割り当てに匿名の mmap を使用します。
ただし、私のテストでは、少なくとも少し古い Linux システムでは、匿名の mmap がデータ セグメントに含まれていることがわかりました。以下のテストプログラムを検討してください。
/* Test mmap and ulimit. */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <string.h>
int print_memstat()
{
char line[80];
FILE *f = fopen("/proc/self/status", "r");
if (!f)
return -1;
while (1) {
if (!fgets(line, 80, f))
break;
if (strncmp(line, "VmSize", 6) == 0
|| strncmp(line, "VmRSS", 5) == 0
|| strncmp(line, "VmData", 6) == 0)
printf("%s", line);
}
fclose(f);
return 0;
}
int main(int argc, char* argv[])
{
if (argc < 3) {
printf("Usage: %s MODE SIZE_IN_MiB\nwhere\n\
MODE=0: Anonymous mmap\n\
MODE=1: mmap of a temporary file\n\
MODE=2: malloc\n", argv[0]);
return 0;
}
int mode = atoi(argv[1]);
long n = atol(argv[2]); // Mem in MiB
n *= 1024*1024;
void *p;
int fd;
char template[] = "/tmp/mmaptestXXXXXX";
switch (mode) {
case 0:
p = mmap(NULL, n, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
if (p == MAP_FAILED) {
perror("anonymous mmap failed");
return 1;
}
break;
case 1:
fd = mkstemp(template);
if (fd == -1) {
perror("mkstemp failed");
return 1;
}
unlink(template);
if (ftruncate(fd, n) == -1) {
perror("ftruncate failed");
return 1;
}
p = mmap(NULL, n, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
if (p == MAP_FAILED) {
perror("mmap failed");
return 1;
}
break;
case 2:
p = malloc(n);
if (!p) {
perror("malloc failed");
return 1;
}
break;
default:
printf("MODE must be 0, 1 or 2\n");
return 0;
}
memset(p, 42, n); // Bump up RSS to approx VSS
print_memstat();
return 0;
}
RHEL5、6、および Ubuntu 12.04 でテスト済み。これらすべてで、anonymous mmap() (MODE=0、glibc malloc() を使用する場合は MODE=2) を使用して割り当てると、データ セクションのサイズ (VmData) が割り当てを含めるために増加します。
EDIT : いくつかのさらなる実験では、匿名の mmap() は /proc/[PID]/status の VmData フィールドで報告されるデータ セクションのサイズを増加させますが、RLIMIT_DATA 制限はヒープ サイズ、つまり brk() にのみ適用されることを示しています。割り当てであり、匿名の mmap() ではありません。ああ!
さて、私の質問は、これが Linux での動作であった期間と、他の Unix システムへの移植性はどの程度かということです。つまり、他の Unix でもデータ セグメント サイズに匿名の mmap が含まれていますか?