ramdisk
Linux內(nèi)核2.0/2.2就已經(jīng)支持,為了能夠使用Ramdisk,我們在編譯內(nèi)核時須將block device中的Ramdisk支持選上,它下面還有兩個選項(xiàng),一個是設(shè)定Ramdisk的大小,默認(rèn)是4096k;
首先查看一下可用的RamDisk,使用ls /dev/ram*
首先創(chuàng)建一個目錄,比如test,運(yùn)行mkdir /mnt/test;
然后對/dev/ram0 格式化創(chuàng)建文件系統(tǒng),運(yùn)行mke2fs /dev/ram0;
最后掛載 /dev/ram0,運(yùn)行mount /dev/ram /mnt/test,就可以象對普通硬盤一樣對它進(jìn)行操作了。
如果umount再加載,只要不重啟linux,那文件依然會保存在/dev/ramX中
ramfs
Ramfs顧名思義是內(nèi)存文件系統(tǒng),它處于虛擬文件系統(tǒng)(VFS)層,而不像ramdisk那樣基于虛擬在內(nèi)存中的其他文件系統(tǒng)(ex2fs)。因而,它無需格式化,可以創(chuàng)建多個,只要內(nèi)存足夠,在創(chuàng)建時可以指定其最大能使用的內(nèi)存大小。
# mount -t ramfs none /testRAM
# mount -t ramfs none /testRAM -o maxsize=2000
umount后再加載數(shù)據(jù)消失
tmpfs
Tmpfs是一個虛擬內(nèi)存文件系統(tǒng),它不同于傳統(tǒng)的用塊設(shè)備形式來實(shí)現(xiàn)的Ramdisk,也不同于針對物理內(nèi)存的Ramfs。Tmpfs可以使用物理內(nèi)存,也可以使用交換分區(qū)
在編譯內(nèi)核時須將
File systems -->> pseudo filesystems -->> Virtual memory file system support支持選上。
mkdir -p /mnt/tmpfs
mount tmpfs /mnt/tmpfs -t tmpfs
同樣可以在加載時指定tmpfs文件系統(tǒng)大小的最大限制:
mount tmpfs /mnt/tmpfs -t tmpfs -o size=32m
size=32m,內(nèi)存的消耗值不是32m,要看真實(shí)使用
umount后再加載數(shù)據(jù)消失。
共享內(nèi)存
(1) ** System V shared memory(shmget/shmat/shmdt) **
(2) ** POSIX shared memory(shm_open/shm_unlink) **
- 用于SYSV共享內(nèi)存,還有匿名內(nèi)存映射;這部分由內(nèi)核管理,用戶不可見;
2.用于POSIX共享內(nèi)存,由用戶負(fù)責(zé)mount,而且一般mount到/dev/shm;依賴于CONFIG_TMPFS;
System V與POSIX共享內(nèi)存都是通過tmpfs實(shí)現(xiàn),但是受的限制卻不相同。也就是說/proc/sys/kernel/shmmax只會影響SYS V共享內(nèi)存,/dev/shm只會影響Posix共享內(nèi)存
Posix共享內(nèi)存區(qū)對象的大小可在任何時刻通過ftruncate修改,而System V 共享內(nèi)存區(qū)對象的大小是在調(diào)用shmget創(chuàng)建時固定下來的。
Posix共享內(nèi)存區(qū)是先調(diào)用shm_open然后再調(diào)用mmap,System V 共享內(nèi)存區(qū)是先調(diào)用shmget再調(diào)用shmat。
mmap
mmap, 它把文件內(nèi)容映射到一段內(nèi)存上(準(zhǔn)確說是虛擬內(nèi)存上), 通過對這段內(nèi)存的讀取和修改, 實(shí)現(xiàn)對文件的讀取和修改,mmap()系統(tǒng)調(diào)用使得進(jìn)程之間可以通過映射一個普通的文件實(shí)現(xiàn)共享內(nèi)存
void *mmap(void *addr, size_t length, int prot, int flags,
int fd, off_t offset);
data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
mmap函數(shù)成功返回指向內(nèi)存區(qū)域的指針
addr,某個特定的地址作為起始地址,當(dāng)被設(shè)置為NULL,系統(tǒng)會在地址空間選擇一塊合適的內(nèi)存區(qū)域。
const char *memname = "/mymem";
//創(chuàng)建在/dev/shm下面, 必須“/”開始
const size_t region_size = sysconf(_SC_PAGE_SIZE);
int fd = shm_open(memname, O_CREAT|O_TRUNC|O_RDWR, 0666);
if (fd == -1)
error_out("shm_open");
r = ftruncate(fd, region_size);
if (r != 0)
error_out("ftruncate");
void *ptr = mmap(0, region_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if (ptr == MAP_FAILED)
error_out("MMAP");
close(fd);
Android 下的property
其中data的創(chuàng)建采用內(nèi)存映射函數(shù)mmap,用dev/properties的原因是因?yàn)閐ev為tmpfs
static int init_workspace(workspace *w, size_t size)
{
void *data;
int fd;
/* dev is a tmpfs that we can use to carve a shared workspace
* out of, so let's do that...
*/
fd = open("/dev/__properties__", O_RDWR | O_CREAT, 0600);
if (fd < 0)
return -1;
if (ftruncate(fd, size) < 0)
goto out;
data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); ------內(nèi)存映射,屬性為MAP_SHARED
if(data == MAP_FAILED)
goto out;
close(fd);
fd = open("/dev/__properties__", O_RDONLY);
if (fd < 0)
return -1;
unlink("/dev/__properties__");
w->data = data;----workspace的地址空間指向內(nèi)存映射的區(qū)域
w->size = size;
w->fd = fd;
return 0;
out:
close(fd);
return -1;
}