我正在尝试在 VirtualBox 中运行的 Ubuntu(32 位)中编译我的 C 项目。编译相关代码需要相当多的内存,至少 3 GB。所以我给了虚拟机 2 GB。加上 2 GB 的可用交换空间,应该足够了。但由于某种原因,gcc 在分配了 900 MB 左右后,出现了内存不足错误。将内存量增加到 2.7 GB(VirtualBox 允许的最大值)没有帮助。一个进程可以使用的内存量似乎有限制。但当我运行时ulimit
,它显示“无限制”。
更新-这是制作日志:
libtool:编译:cc -msse2 -I. -I/home/cleong/qb -DPHP_ATOM_INC -I/home/cleong/qb/include -I/home/cleong/qb/main -I/home/cleong/qb -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/TSRM -I/usr/include/php5/Zend -I/usr/include/php5/ext -I/usr/include/php5/ext/date/lib -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DHAVE_CONFIG_H -g -O2 -c /home/cleong/qb/qb_interpreter_gcc.c -fPIC -DPIC -o .libs/qb_interpreter_gcc.o
cc1:在总共分配 924852224 字节后,分配 408 字节内存不足
制作:*** [qb_interpreter_gcc.lo] 错误 1
/bin/time -v 的输出:
Command exited with non-zero status 2
Command being timed: "make"
User time (seconds): 62.09
System time (seconds): 11.28
Percent of CPU this job got: 64%
Elapsed (wall clock) time (h:mm:ss or m:ss): 1:53.02
Average shared text size (kbytes): 0
Average unshared data size (kbytes): 0
Average stack size (kbytes): 0
Average total size (kbytes): 0
Maximum resident set size (kbytes): 1848592
Average resident set size (kbytes): 0
Major (requiring I/O) page faults: 9433
Minor (reclaiming a frame) page faults: 1391779
Voluntary context switches: 5642
Involuntary context switches: 6069
Swaps: 0
File system inputs: 630360
File system outputs: 1376
Socket messages sent: 0
Socket messages received: 0
Signals delivered: 0
Page size (bytes): 4096
Exit status: 2
gcc的版本是4.7.2。
源代码在这里:
https://github.com/chung-leong/qb
这是一个 PHP 扩展。构建过程使用 phpize。
更新 - 我在 32 位 Mageia 3 中遇到了同样的问题,其中还包括 gcc 4.7.2。故障发生在 2.7 GB 左右。在 64 位环境中,不会发生这种情况。
如果我安装 gcc 4.6.3 并使用它进行构建,它就可以工作。
答案1
事实上,-O1
64 位 Ubuntu 可以在优化级别为或更低的情况下编译该项目,这意味着问题出在 gcc 的优化阶段。
我猜测您项目中的某些源文件是由于版本 4.7.2 中引入的 gcc 优化器存在错误或效率低下而导致的,从而导致了不合理数量的内存使用。
所以我的建议是:
- 32 位版本的 gcc 只能访问 2-3 GB 的内存(无论交换大小是多少)。
- 扩大交换空间,但如果这没有帮助,请继续阅读。无论如何,对于 32 位 gcc,它可以使用的内存量是有限制的。
- 通过逐个编译源文件,找到导致问题的源文件。如果所有源文件都是这样,那么问题就出在某些包含文件上。
- 如果问题不在于包含文件,则进一步将有问题的源文件分成几个部分,直到不再出现错误或找到导致错误的具体函数。
- 作为临时解决方法,请修改 make 文件以便使用 编译该函数
-O1
。本例中的问题出在 gcc 本身,您可以在错误报告中提交该函数(连同全部你的包含文件)。 - 当然,您也可以选择编译整个项目,
-O1
这对于 PHP 扩展来说应该足够了,或者暂时继续使用 gcc 4.6.3。 - 继续尝试对 gcc 进行新的更新,因为该错误可能会被修复(或消除低效率),与您的错误报告无关。
答案2
哇,这是一个项目!
看起来你必须使用在 64 位主机系统上运行的交叉编译器来构建此项目。如果我没记错的话,Firefox 就是以这种方式构建的。
GCC 可能已经因为虚拟内存碎片而耗尽了它的所有地址空间,而且您在统计数据中看到的 900 MB 可能是已提交的物理内存,通常低于保留的虚拟内存。
此外,无论您拥有多大的物理内存和交换文件,每个 32 位进程最多可以访问 2Gb 的内存。