【发布时间】:2020-11-25 14:48:04
【问题描述】:
上下文: 我在使用 ACE_Mem_Map 创建的代码中使用内存映射文件。观察到内存映射文件消耗的磁盘空间比预期的要多。
场景: 我有一个包含 15KB 字符数组的结构。我已经为这个结构的数组创建了一个内存映射文件,文件大小约为 2GB。
- 如果我尝试访问 char 数组的几个字节(比如 256),则消耗的文件大小显示为 521 MB,但文件系统显示的实际磁盘使用量(使用 df -h)超过 3GB。
- 如果我访问内存的所有字节,则文件大小和磁盘使用量均显示为 2 GB。
环境: 操作系统:Oracle Linux 7.3 内核版本:3.10.0/4.1.12
代码:
#include<ace/Mem_Map.h>
#include <stdio.h>
#define TEST_BUFF_SIZE 15*1024
typedef struct _test_struct_ {
char test[TEST_BUFF_SIZE];
_test_struct_() {
reset();
}
void reset() {
/* Issue replicating */
memset(test, '\0', 256);
/* Issue not replicating */
memset(test, '\0', TEST_BUFF_SIZE);
}
}TestStruct_t;
int main(int argc, char *argv[]) {
if(3 != argc) {
printf("Usage: %s <num of blocks> <filename>\n",
argv[0]);
return -1;
}
ACE_Mem_Map map_buf_;
size_t num_of_blocks = strtoull(argv[1], NULL, 10);
size_t MAX_SIZE = num_of_blocks*sizeof(TestStruct_t);
char* mmap_file_name = argv[2];
printf("num_of_blocks[%llu], sizeof(TestStruct_t)[%llu], MAX_SIZE[%llu], mmap_file_name[%s]\n",
num_of_blocks,
sizeof(TestStruct_t),
MAX_SIZE,
mmap_file_name);
TestStruct_t *base_addr_;
ACE_HANDLE fp_ = ACE_OS::open(mmap_file_name,O_RDWR|O_CREAT,
ACE_DEFAULT_OPEN_PERMS,0);
if (fp_ == ACE_INVALID_HANDLE)
{
printf("Error opening file\n");
return -1;
}
map_buf_.map(fp_,MAX_SIZE,PROT_WRITE,MAP_SHARED);
base_addr_ = (TestStruct_t*)map_buf_.addr();
if (base_addr_ == MAP_FAILED)
{
printf("Map init failure\n");
ACE_OS::close(fp_);
return -1;
}
printf("map_buf_ size[%llu]\n",
map_buf_.size());
for(size_t i = 0; i < num_of_blocks; i++) {
base_addr_[i].reset();
}
return 0;
}
谁能解释一下为什么会发生场景 1??
注意:在场景 1 中,如果我复制生成的 mmap 文件然后删除该副本,那么额外的 2.5GB 磁盘空间将被释放。不知道原因
【问题讨论】:
-
C 结构不能有成员函数。
-
@JohnBollinger,即使我删除了成员函数,问题仍在复制
-
即使没有成员函数,关键是这不是 C 问题。 ACE 是一个 C++ 工具包,所提供的代码的其他方面也特定于 C++。事实上,由于程序使用 ACE 来映射文件,而不是直接调用
mmap,所以目前的问题是 ACE 特有的。 -
当您谈论实际的“文件大小”时,您是如何衡量的?
ls? -
我正在使用 du 和 stat 命令来验证文件大小