You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker容器中使用make -j编译GCC项目时出现内存分配错误

问题

在Docker容器内使用make -j编译项目时触发内存相关错误,错误信息如下:

/root/projects/obj/linux_debug/src/myos_make/libmyos.a: error adding symbols: Cannot allocate memory
/usr/protobuf-3.9.2/lib/libprotobuf.a: error adding symbols: Bad address

但以下两种场景编译均正常:

  • 容器内不使用-j选项编译
  • 宿主机上使用-j选项编译

对应的Dockerfile内容如下:

#
# This docker must be built from projects/src folder as context
#

FROM ubuntu:18.04 as base

# copy the dockerfile to make it possible to keep track of the cntent of the image
COPY ./docker_build/docker_files/Dockerfile.ubuntu18.04-builder $HOME/.

# Disable Prompt During Packages Installation
ARG DEBIAN_FRONTEND=noninteractive

# Update Ubuntu Software repository
RUN apt update -y && apt upgrade -y

# Install base utils
RUN apt install -y \
       nano \
       wget \
       sudo \
       curl \
       && apt clean -y 


# Install additional packages needed for build.
RUN apt install -y \
       nasm \
       pkg-config \
       bc \
       python \
       python3 \
       python3-pip \
       sshpass \
       libapr1 \
       libapr1-dev \
       && apt clean -y 

RUN apt install -y  \
       rpm \
       libaio-dev \
       libnuma-dev \
       numactl \
       valgrind \
       openssl \
       libssl-dev \
       ldap-utils \
       libldap2-dev \
       libncurses5-dev \
       libncursesw5-dev \
       uuid-dev \
       ncurses-base \
       expat \
       libfuse-dev \
       cmake \
       build-essential \
       autotools-dev \
       autoconf \
       automake \
       doxygen \
       linux-headers-4.15.0-173-generic \
       g++-multilib \
       lib32z1-dev \
       libasan4 \
       software-properties-common \
       libtool \
       unzip \
       xsltproc \
       && apt clean -y 

RUN ln -s /usr/bin/doxygen /bin/doxygen

# install GCC compiler
RUN add-apt-repository ppa:ubuntu-toolchain-r/test -y \
       && apt update -y\
       && apt install gcc-10 -y \
       && apt install g++-10 -y \
       && apt clean -y && \
       update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 60 --slave /usr/bin/g++ g++ /usr/bin/g++-10 && \
       update-alternatives --config gcc 

RUN curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py && \
       python get-pip.py

RUN ln -sf /usr/local/bin/pip2 /usr/bin/pip
RUN pip install \
       pyyaml \
       jinja2 \
       gcovr


FROM base as env-prepare

COPY external/protobuf /protobuf

RUN cd protobuf  && ./build_proto.sh

FROM base as builder

COPY --from=env-prepare /usr/protobuf-3.9.2/ /usr/protobuf-3.9.2/
COPY --from=env-prepare /usr/protobuf-c-1.3.2/ /usr/protobuf-c-1.3.2/

COPY docker_build/docker-image-release /etc/docker-image-release

ARG UID=1000
USER ${UID}

# This entrypoint is to make everything run inside bash, so the devtools script will alway run before the command
ENTRYPOINT [ "/bin/bash", "-c" ]

解决方案

1. 手动扩容容器内存

Docker默认给容器分配的内存配额有限,并发编译时极易耗尽内存。启动容器时指定更大的内存:

docker run -it --memory=4g --memory-swap=4g [你的镜像名称]

可根据实际编译需求调整数值,比如8g。

2. 限制make -j的并发线程数

不要使用默认的自动线程数(通常等于CPU核心数),手动指定更保守的数值,平衡编译速度与内存占用:

make -j4

可以从-j2开始测试,逐步调整到合适的线程数。

3. 排查内存使用情况

启动容器后执行free -h,查看编译过程中内存是否被耗尽。如果宿主机本身内存不足,需先扩容宿主机内存。

4. 优化编译参数

  • 临时关闭编译优化:在Makefile中添加CFLAGS+=-O0,减少内存占用。
  • 启用目标文件瘦身参数:添加CFLAGS+=-ffunction-sections -fdata-sections,降低静态库文件大小。
  • 关闭ASAN:Dockerfile中安装了libasan4,如果编译默认启用地址 sanitizer,会大幅增加内存消耗,可临时关闭该选项。

5. 修改Docker daemon默认内存配置

如果频繁遇到这类问题,可修改Docker daemon配置文件(通常为/etc/docker/daemon.json),设置全局默认内存限制:

{
  "resources": {
    "defaults": {
      "memory": "4g"
    }
  }
}

修改后重启Docker服务:systemctl restart docker

内容的提问来源于stack exchange,提问作者Alex Belous

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 06:00:17