Turn from: http://www.perfgeeks.com/?p=723
Mmap () and MMAP2 () are often visible through strace statistical system calls. System call MMAP () can map a file to memory (process space). This allows the operation of the file to be converted to memory operations to avoid more lseek () and read (), write () operations, which is especially beneficial for large files or frequently accessed files. But one thing must be clear: Mmap's addr and offset must be aligned to the bounds of a memory page size, that is, the memory map is often an integer multiple of the page size, otherwise the maaped_file_size%page_size memory space will be wasted.
To demonstrate, convert the characters in the file/tmp/file_mmap to uppercase and use the Mmap and Read/write two methods respectively.
/ *
* @file: t_mmap.c
* /
#include <stdio.h>
#include <ctype.h>
#include <sys / mman.h> / * mmap munmap * /
#include <sys / types.h>
#include <sys / stat.h>
#include <fcntl.h>
#include <unistd.h>
int main (int argc, char * argv [])
{
int fd;
char * buf;
off_t len;
struct stat sb;
char * fname = "/ tmp / file_mmap";
fd = open (fname, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
if (fd == -1)
{
perror ("open");
return 1;
}
if (fstat (fd, & sb) == -1)
{
perror ("fstat");
return 1;
}
buf = mmap (0, sb.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (buf == MAP_FAILED)
{
perror ("mmap");
return 1;
}
if (close (fd) == -1)
{
perror ("close");
return 1;
}
for (len = 0; len <sb.st_size; ++ len)
{
buf [len] = toupper (buf [len]);
/ * putchar (buf [len]); * /
}
if (munmap (buf, sb.st_size) == -1)
{
perror ("munmap");
return 1;
}
return 0;
}
#gcc --o t_mmap t_mmap.c
#strace ./t_mmap
open ("/ tmp / file_mmap", O_RDWR | O_CREAT, 0600) = 3 // open, returns fd = 3
fstat64 (3, (st_mode = S_IFREG | 0644, st_size = 18, ...)) = 0 // fstat, which is the file size 18
mmap2 (NULL, 18, PROT_READ | PROT_WRITE, MAP_SHARED, 3, 0) = 0xb7867000 // mmap file fd = 3
close (3) = 0 // close file fd = 3
munmap (0xb7867000, 18) = 0 // munmap, remove the memory map from 0xb7867000 here
Although you do not see the read/write write file operation, the content in the file/tmp/file_mmap has changed from www.perfgeeks.com to WWW.PERFGEEKS.COM. Here mmap is 0 (NULL), Offset is 18, not an integer multiple of a memory page, that is, 4078bytes (4kb-18) memory space is wasted.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <sys / types.h>
#include <sys / stat.h>
#include <fcntl.h>
#include <unistd.h>
int main (int argc, char * argv [])
{
int fd, len;
char * buf;
char * fname = "/ tmp / file_mmap";
ssize_t ret;
struct stat sb;
fd = open (fname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
if (fd == -1)
{
perror ("open");
return 1;
}
if (fstat (fd, & sb) == -1)
{
perror ("stat");
return 1;
}
buf = malloc (sb.st_size);
if (buf == NULL)
{
perror ("malloc");
return 1;
}
ret = read (fd, buf, sb.st_size);
for (len = 0; len <sb.st_size; ++ len)
{
buf [len] = toupper (buf [len]);
/ * putchar (buf [len]); * /
}
lseek (fd, 0, SEEK_SET);
ret = write (fd, buf, sb.st_size);
if (ret == -1)
{
perror ("error");
return 1;
}
if (close (fd) == -1)
{
perror ("close");
return 1;
}
free (buf);
return 0;
}
#gcc --o t_rw t_rw.c
open ("/ tmp / file_mmap", O_RDWR | O_CREAT, 0600) = 3 // open, fd = 3
fstat64 (3, (st_mode = S_IFREG | 0644, st_size = 18, ...)) = 0 // fstat, where the file size is 18
brk (0) = 0x9845000 // brk, returns the current break point
brk (0x9866000) = 0x9866000 // malloc allocates memory, the current last address of the heap
read (3, "www.perfgeeks.com \ n", 18) = 18 // read
lseek (3, 0, SEEK_SET) = 0 // lseek
write (3, "WWW.PERFGEEKS.COM \ n", 18) = 18 // write
close (3) = 0 // close
This reads the contents of the file through read (), ToUpper (), and invokes write () writeback file. Because the file is too small to reflect the disadvantage of Read ()/write (): Frequent access to large files requires multiple Lseek () to determine the location. Each time you edit the read ()/write (), double data in physical memory. Of course, it is not possible to ignore the cost of creating and maintaining mmap () data structures. Need to note: There is no specific test mmap vs Read/write, that is, can not be a language to assert who is inferior, specific application scenarios specific evaluation analysis. You just have to remember: mmap memory-mapped files, operation memory is the operation of the file, you can save a lot of system kernel calls (Lseek, read, write). mmap () vs malloc ()
When you use Strace debugging, you can usually see a figure that creates an anonymous memory map through Mmap (). For example, when you enable DL (' apc.so '), you can see the following statement.
MMAP2 (NULL, 31457280, prot_read| Prot_write, map_shared| Map_anonymous,-1, 0) = 0xb5ce7000//30m
It is common to use MMAP () for anonymous memory mappings to capture memory and meet some special requirements. The so-called anonymous memory mapping, refers to the mmap (), set a special logo map_anonymous, and FD can be ignored (-1). Some operating systems (like FreeBSD), which do not support flag map_anonymous, can be mapped to device file/dev/zero to implement anonymous memory mappings. The advantage of allocating memory using mmap () is that the page has been filled up to 0, and the malloc () has not been initialized after allocating memory, and the memory needs to be initialized by memset (). In addition, malloc () may call BRK () or call MMAP2 () when allocating memory. is to allocate a small amount of memory (less than or equal to 128kb), malloc () calls the BRK () to increase the breakpoint, allocating memory in the heap area, and when allocating a large chunk of memory (greater than 128KB), malloc () will call MMAP2 () to allocate a chunk of memory, independent of the heap, outside the heap. Similarly, the memory that is allocated by the free () memory map is immediately retrieved by the system, and a piece of memory in the free () heap is not immediately reclaimed by the system, and GLIBC will retain it for the next malloc () use.
Here's a demo of malloc () using BRK () and MMAP2 ().
* * FILE:T_MALLOC.C
/
#include <stdio.h>
#include <string.h>
#include < stdlib.h>
int main (int argc, char *argv)
{
char *brk_mm, *mmap_mm;
printf ("-----------------------\ n");
BRK_MM = (char *) malloc (MB);
memset (brk_mm, ' the ');
MMAP_MM = (char *) malloc (+ * 1024);
memset (mmap_mm, ' n ', 500*1024);
Free (brk_mm);
Free (mmap_mm);
printf ("-----------------------\ n");
return
1;
}
#gcc –o t_malloc t_malloc.c
#strace./t_malloc
Write (1, "-----------------------\ n",------------- ----------) =
brk (0) = 0x85ee000
brk (0x860f000) = 0x860f000//malloc (MB)
MMAP2 ( NULL, 516096, prot_read| Prot_write, map_private| Map_anonymous,-1, 0