Mmap() l'ensemble d'un fichier de grande taille

Je suis en train de "mmap" un fichier binaire (~ 8 go) en utilisant le code suivant (test.c).

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define handle_error(msg) \
  do { perror(msg); exit(EXIT_FAILURE); } while (0)

int main(int argc, char *argv[])
{
   const char *memblock;
   int fd;
   struct stat sb;

   fd = open(argv[1], O_RDONLY);
   fstat(fd, &sb);
   printf("Size: %lu\n", (uint64_t)sb.st_size);

   memblock = mmap(NULL, sb.st_size, PROT_WRITE, MAP_PRIVATE, fd, 0);
   if (memblock == MAP_FAILED) handle_error("mmap");

   for(uint64_t i = 0; i < 10; i++)
   {
     printf("[%lu]=%X ", i, memblock[i]);
   }
   printf("\n");
   return 0;
}

test.c est compilé à l'aide de gcc -std=c99 test.c -o test et file de test renvoie: test: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped

Bien que cela fonctionne bien pour les petits fichiers, j'obtiens une erreur de segmentation quand j'essaye de charger un gros. Le programme retourne en fait:

Size: 8274324021 
mmap: Cannot allocate memory

J'ai réussi à cartographier l'ensemble du dossier à l'aide de boost::iostreams::mapped_file mais je veux le faire à l'aide de C et des appels système. Quel est le problème avec mon code?

  • vous devez ouvrir le fichier avec le O_LARGEFILE drapeau. vérifier le manuel. pas sûr que >fichiers de 4 go peut être mmaped.
  • Ne pouvons pas reproduire ici. Votre code fonctionne très bien sur un 9G fichier. Combien (RAM+SWAP) avez-vous? Quelle est votre /proc/sys/vm/overcommit_memory politique?
  • total: 1984, utilisé: 1923, gratuit de 60} Swap{ total: 2021, utilisé: 0, gratuit: 2021} $ cat /proc/sys/vm/overcommit_memory #retourne 0
  • le drapeau serait nécessaire à partir d'un ordinateur 32 bits. Ref
  • désolé, je viens de remarquer x86_64
  • On dirait que vous avez eu la réponse à votre problème particulier, mais cette erreur peut aussi être causée par avoir ulimit -v trop bas pour la quantité de mémoire que vous demandez, quelle que soit la quantité de mémoire/swap que vous avez.
  • Avez-vous essayez d'exécuter strace pour voir si vous êtes en trébuchant sur un ENOMEM?

InformationsquelleAutor Emer | 2011-08-28