提问
你是否为了解QFileInfoList而惊喜过?你是否还不曾对QFileInfoList苦恼过?
不管是与不是,我都将抛出疑问,你知道它的细节吗?你了解过,当一个文件夹过于庞大时,它所带来的威胁?一次简单的访问文件夹,或许没有什么问题,但如果短时间内反复访问一个正在增大的文件夹,你是否考虑过会出现什么情况?
代码
void test()
{
……
QFileInfoList file_list = dir.entryInfoList(QDir::Files | QDir::Hidden | QDir::Dirs | QDir::NoDotAndDotDot);
……
}
我们需要警醒,QFileInfoList时会申请内存的!
内存分配的核心原因
QFileInfoList的底层实现:QFileInfoList是QList < QFileInfo > 的别名。QList在动态添加元素时,会根据元素数量自动管理内存:
- 当首次添加元素时,QList会分配初始内存块(通常预分配一定容量)。
- 当元素数量超过当前容量时,QList会触发内存重分配(通过realloc或类似机制),扩展存储空间。
每个QFileInfo对象本身占用固定内存(约几十字节,包含文件路径、大小、权限等元数据),这些对象在QList中以连续或非连续方式存储(取决于Qt版本和优化策略)。
entryInfoList()的执行逻辑:
该方法会遍历目录中的所有条目(包括文件、隐藏文件、子目录,但排除.和…)。对每个符合过滤条件的条目,创建一个QFileInfo对象,并将其添加到返回的QList中。即使目录为空,也会返回一个空列表(此时内存分配主要用于QList的元数据,如容量、大小等)。
内存分配的细节
- 固定开销:
QList的内存管理需要存储元素数量、容量指针、数据指针等元数据(通常占用几十字节)。 - 动态开销:
每个QFileInfo对象占用约48-64字节(取决于QString的存储优化,如路径字符串可能共享或按需分配)。若目录包含N个条目,则QList至少需要分配N * sizeof(QFileInfo) + 固定开销的内存。若QList容量不足,会按指数增长(如1.5倍或2倍)重新分配内存,导致临时内存占用增加(但最终会释放旧内存)。 - 隐藏文件与目录的处理:QDir::Hidden和QDir::Dirs标志会额外包含隐藏文件和子目录,增加返回的条目数量,从而增加内存分配量。QDir::NoDotAndDotDot排除了.(当前目录)和…(上级目录),减少两个条目,但影响较小。
内存管理的注意事项
- 自动释放:当file_list超出作用域时(如离开代码块),QList的析构函数会自动释放所有QFileInfo对象和内部内存。
- 隐式共享(Copy-on-Write):若将file_list传递给其他函数或存储在类成员中,Qt的隐式共享机制会延迟实际内存复制,直到数据被修改。
- 性能优化:对于大目录,可通过QDir::entryList()结合QFileInfo按需获取信息,避免一次性加载所有条目到内存。
- 验证方法
内存分析工具:使用Valgrind、ASan(AddressSanitizer)或Qt Creator的内存分析工具,观察调用entryInfoList()前后内存的变化。 - 代码测试:在循环中调用该代码,监控进程内存占用(如Windows任务管理器、Linux的top命令),可观察到内存分配趋势。
结论
这行代码会申请内存,主要用于存储QFileInfo对象列表和QList的元数据。内存分配量与目录中的条目数量(文件、隐藏文件、子目录)成正比,且受QList的内存管理策略影响。在Qt中,这种内存分配是必要的,但需注意大目录可能导致的内存开销,可通过分批处理或按需加载优化性能。
后果
如果对其并不在意,那么代表你还没有到接触这一层次的项目。与QFileInfo类似的,比比皆是,如果不对其加以管制,将会导致整个系统资源竞争激烈,最终卡顿,或者崩溃。在任何一个对内存有严格要求的项目中,规避QFileInfo等类似的内存异常申请,才是项目扩展的良好基础。
22

被折叠的 条评论
为什么被折叠?



