由于我阅读了Linux编程接口书(非常好读),我在Linux中发现了文件漏洞。因此使用像Ext4这样的Unix文件格式可以打开一个新的文件写入1000字节寻找到1000.000.000的位置写入另外1000个字节并且取决于文件格式的块大小最终为一个块大小消耗仅2048字节的文件1024或512。
所以基本上这个文件被创建为1GB + 1000字节长的文件,其中只使用了两个实际驱动器空间块。
我可以删除文件中间,强制系统取消分配驱动器上的这些块吗?
是否有一个等价的地方我分配(共享内存)有或没有文件支持它在哪里还有孔,只是在写入内存页时填充?
分配1GB共享内存会很好,但是在必要之前永远不要完全使用它,只是为了避免重新映射,如果共享内存块应该增长。
答案 0 :(得分:3)
我可以删除文件中间,强制系统取消分配驱动器上的这些块吗?
您可能想要特定于Linux的fallocate(2);请注意,它可能不适用于某些文件系统(例如NFS,VFAT,...),因为某些filesystems没有漏洞。另请参阅lseek(2) SEEK_HOLE
,posix_fadvise(2),madvise(2),memfd_create(2)等...
原始block devices(如磁盘分区,USB密钥或SSD)没有任何漏洞(但您可以mmap
进入它们)。孔是文件系统软件工件。
这是矛盾的。如果内存是共享,则使用(通过事物 - 通常是另一个进程 - 您共享该内存)。如果您真的需要shm_overview(7)(并仔细阅读 shared memory),请阅读mmap(2)。详细了解virtual memory,address space,paging,MMU s,page faults,operating systems,kernels,{{3} },mmap,demand paging,copy-on-write,memory map,ELF ...在终端中尝试分配1GB共享内存但从不使用它会很好
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
重新分配将使用一些资源(例如,消耗一些交换空间)。
另请阅读SBCL并仔细阅读Advanced Linux Programming以及相关系统调用的特定手册页。
另请阅读syscalls(2)。这是一个Linux功能,我不喜欢并且通常会禁用(例如通过memory overcommitment)。
顺便说一句,proc(5)是Linux kernel。您可以从free software下载其源代码并研究源代码。你也可以写一些实验代码。然后提出另一个更集中的问题,显示您的代码和实验结果。