Linux中的文件孔和共享内存?

时间:2015-07-15 07:28:06

标签: c linux file memory

由于我阅读了Linux编程接口书(非常好读),我在Linux中发现了文件漏洞。因此使用像Ext4这样的Unix文件格式可以打开一个新的文件写入1000字节寻找到1000.000.000的位置写入另外1000个字节并且取决于文件格式的块大小最终为一个块大小消耗仅2048字节的文件1024或512。

所以基本上这个文件被创建为1GB + 1000字节长的文件,其中只使用了两个实际驱动器空间块。

我可以删除文件中间,强制系统取消分配驱动器上的这些块吗?

是否有一个等价的地方我分配(共享内存)有或没有文件支持它在哪里还有孔,只是在写入内存页时填充?

分配1GB共享内存会很好,但是在必要之前永远不要完全使用它,只是为了避免重新映射,如果共享内存块应该增长。

1 个答案:

答案 0 :(得分:3)

  

我可以删除文件中间,强制系统取消分配驱动器上的这些块吗?

您可能想要特定于Linux的fallocate(2);请注意,它可能不适用于某些文件系统(例如NFS,VFAT,...),因为某些filesystems没有漏洞。另请参阅lseek(2) SEEK_HOLEposix_fadvise(2)madvise(2)memfd_create(2)等...

原始block devices(如磁盘分区,USB密钥或SSD)没有任何漏洞(但您可以mmap进入它们)。孔是文件系统软件工件。

  

分配1GB共享内存但从不使用它会很好

这是矛盾的。如果内存是共享,则使用(通过事物 - 通常是另一个进程 - 您共享该内存)。如果您真的需要shm_overview(7)(并仔细阅读 shared memory),请阅读mmap(2)。详细了解virtual memoryaddress spacepagingMMU s,page faultsoperating systemskernels,{{3} },mmapdemand pagingcopy-on-writememory mapELF ...在终端中尝试cat /proc/$$/maps命令,并了解输出(见sparse files ...)。

也许你想预先分配一些地址空间范围,以后真正分配虚拟内存。使用Linux版proc(5)可以实现这一点。

要预先分配千兆字节的内存范围,您首先应使用mmap

致电MAP_NORESERVE
size_t onegiga = 1L<<30;
void* startad = mmap(NULL, onegiga, PROT_NONE, 
                MAP_ANONYMOUS|MAP_NORESERVE|MAP_SHARED,
                -1, 0);
if (startad==MAP_FAILED) { perror("mmap MAP_NORESERVE"); exit(EXIT_FAILURE); }
void* endad = (char*)startad + onegiga;

MAP_NORESERVE不消耗大量资源(即不占用交换空间,这不是保留的,因此是标志的名称)。它是预分配地址空间,因为进一步的mmap调用(没有MAP_FIXED)将不会在返回的范围内给出一个地址(除非你munmap部分地址)。

稍后,你可以使用前一段内的MAP_FIXED,以页面大小的倍数(通常为4K字节)分配一些子段,例如

size_t segoff = 1024*1024; // or something else such that ....
assert (segoff >=0  && segoff < onegiga && segoff % sysconf(_SC_PAGESIZE)==0);
size_t segsize = 65536; // or something else such that ....
assert (segsize > 0 && segsize % sysconf(_SC_PAGESIZE)==0 
        && startad + segoffset + segsize < endad);
void* segmentad = mmap(startad + segoffset, segsize,
                       PROT_READ|PROT_WRITE, 
                       MAP_FIXED | MAP_PRIVATE, 
                       -1, 0);
if (segmentad == MAP_FAILED) { perror("mmap MAP_FIXED"); exit(EXIT_FAILURE); }

使用MAP_FIXED重新分配将使用一些资源(例如,消耗一些交换空间)。

IIRC,mmap(2)运行时和垃圾收集使用这些技巧。

另请阅读SBCL并仔细阅读Advanced Linux Programming以及相关系统调用的特定手册页。

另请阅读syscalls(2)。这是一个Linux功能,我不喜欢并且通常会禁用(例如通过memory overcommitment)。

顺便说一句,proc(5)Linux kernel。您可以从free software下载其源代码并研究源代码。你也可以写一些实验代码。然后提出另一个更集中的问题,显示您的代码和实验结果。