Qt编译时出现”out of memory allocating“解决方法

本文详细记录了一次在使用Qt开发过程中遇到的编码问题,即Qt会将源文件编码自动更改为ANSI,导致程序运行错误。作者通过手动将所有.h和.cpp文件编码修改为UTF-8,成功解决了该问题。

遇到这奇葩问题也是有好几次了。

这次终于找到原因了。

手动把所有的.h和.cpp的编码改为UFT-8,就能解决。

很奇怪Qt经常偷偷地把源文件的编码改为ANSI

<think> 我们收到了用户的错误信息:“out of memory allocating 16 bytes after a total of 527805824 bytes”。这意味着在已经分配了大约527MB内存后,尝试再分配16字节时失败了。这通常是由于系统内存不足或编译器/构建工具的内存限制造成的。 引用[1]展示了类似的错误(分配3355443200字节失败),引用[2]介绍了C++17的内存管理优化技术,引用[3]则指出增加编译器线程数会增加内存使用量。结合这些信息,我们可以从以下几个方面尝试解决: 1. **减少并行编译任务数**:make默认会根据CPU核心数启动多个并行任务,每个任务都会消耗内存。减少并行任务数可降低总内存需求。 - 方法:在make命令中加入`-jN`参数,其中`N`为较小的数字(如1或2),例如:`make -j2` 2. **优化代码和构建配置**: - 检查是否有不必要的头文件包含或大型静态数据,减少单个编译单元的内存占用。 - 使用预编译头文件(PCH)减少重复编译开销。 - 启用编译器优化选项(如`-O1`或`-Os`),某些优化可能减少编译时的内存需求。 3. **增加系统可用内存**: - 关闭其他占用内存的应用程序。 - 增加系统交换空间(Swap),为操作系统提供更多虚拟内存。 4. **升级硬件或使用64位工具链**: - 如果当前使用32位编译器,其进程内存上限通常为2GB。改用64位编译器可突破此限制。 5. **使用内存池技术(高级)**: - 如引用[2]所述,C++17的`std::pmr`允许定制内存分配策略。虽然这主要针对运行时的内存管理,但编译时也可通过优化内存分配器降低开销(需要修改构建工具或编译器配置,较复杂)。 6. **分模块编译**: - 将项目拆分为独立模块分别编译,最后再链接。这样每次编译只需处理部分代码。 下面是一个逐步操作指南: ### 步骤1: 减少并行任务 ```bash # 尝试单任务编译 make -j1 # 若仍失败,继续尝试减少其他内存占用 ``` ### 步骤2: 检查系统内存状态 - Linux: 使用`free -h`查看内存和交换空间使用情况。 - Windows: 通过任务管理器检查内存占用。 ### 步骤3: 增加交换空间(Linux示例) ```bash # 创建4GB交换文件 sudo fallocate -l 4G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile ``` ### 步骤4: 使用32位编译器的特殊处理 如果使用32位工具链,可尝试: - Linux: 安装`linux32`并用`linux32 make ...`启动编译,以解除虚拟地址空间限制(需系统支持)。 - Windows: 使用`EDITBIN`工具为编译器可执行文件增加`/LARGEADDRESSAWARE`标志,允许访问更多内存(最多3GB)。 ### 步骤5: 寻求替代方案 - 使用更节省内存的编译器(如Clang可能比GCC内存效率高)。 - 升级物理内存或改用更高配置的机器编译。 §§相关问题§§ 1. 如何监控编译过程中的内存使用情况? 2. `std::pmr`能否应用于编译器自身以减少编译时的内存消耗? 3. 还有哪些编译技巧可以降低内存占用? </think> ### 解决编译时内存溢出错误的方法 您在编译时遇到的 `out of memory allocating 16 bytes after a total of 527805824 bytes` 错误表明编译器在分配约 527MB 内存后无法再分配 16 字节空间。结合引用内容,以下是系统性的解决方案: #### 一、 立即缓解措施 1. **减少并行编译任务数** ```bash make -j2 # 将并行任务数从默认值降到2 ``` - 引用[3]指出线程数增加会导致内存需求上升,减少并行任务可显著降低峰值内存[^3] - 通过 `nproc` 查看 CPU 核心数,建议设置为 `实际核心数/2` 2. **释放系统内存** - 关闭非必要应用程序 - Linux 清理缓存: ```bash sync; echo 3 | sudo tee /proc/sys/vm/drop_caches ``` 3. **增加交换空间(Swap)** ```bash # 临时增加2GB交换空间 sudo dd if=/dev/zero of=/swapfile bs=1M count=2048 sudo mkswap /swapfile sudo swapon /swapfile ``` #### 二、 编译器级优化 1. **启用增量编译** ```cmake SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-fat-lto-objects") ``` - 减少全量编译内存需求 2. **分割编译单元** ```bash # 手动编译大文件 g++ -c large_file.cpp -o large_file.o make # 再执行完整构建 ``` 3. **使用内存友好的优化级别** ```bash export CXXFLAGS="-O1" # 避免-O2/-O3的高内存优化 ``` #### 三、 内存管理优化(基于引用[2]) 1. **应用 C++17 内存资源管理** ```cpp #include <memory_resource> #include <vector> std::pmr::monotonic_buffer_resource pool; std::pmr::vector<int> vec(&pool); // 使用内存池分配 ``` - 通过 `std::pmr` 实现定制化内存分配,防止内存碎片[^2] 2. **使用内存池分配器** ```cpp class CustomAllocator : public std::pmr::memory_resource { void* do_allocate(size_t bytes, size_t alignment) override { return custom_mem_pool.allocate(bytes); // 连接预分配池 } }; ``` #### 四、 系统级配置 | 调整项 | Linux 命令 | Windows 操作 | |------------------|-------------------------------------------|----------------------------------| | 进程内存限制 | `ulimit -v 2097152` (设为2GB) | 编辑`EDITBIN`可执行文件内存标志 | | 编译器内存限制 | `export GCC_EXEC_PREFIX=lowmem` | `/Zm` 编译参数调整内存分配器 | | 虚拟内存扩展 | `sysctl -w vm.overcommit_memory=1` | 调整系统虚拟内存设置 | #### 五、 深度优化方案 1. **识别内存泄漏点** ```bash valgrind --tool=massif make # 生成内存使用热力图 ``` - 分析峰值内存消耗的编译阶段 2. **升级工具链** - 使用 Clang 替代 GCC(通常内存效率提升 20-30%) - 启用 64 位编译工具链:`-m64` 3. **代码重构建议** - 减少模板实例化爆炸:用 `extern template` 显式实例化 - 分割巨型源文件(>2000行代码) - 避免递归包含头文件 > **关键提示**:当错误显示 `after a total of XXX bytes` 时,XXX 值接近系统/进程内存上限,表明需要根本性优化而非临时调整[^1][^3]。
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值