Skip to content

Commit 02971dd

Browse files
joshknshoes
andauthored
Use jemalloc for our memory allocation (#2265)
This adds two new build stages, one for building jemalloc with GCC 14, and one for building a statically linked fwup. (This fwup change was included in this PR because it made testing the Dockerfile changes easier - I have a Mac.) Using [jemalloc](https://github.com/facebook/jemalloc) (this link leads to the facebook fork of jemalloc, which is under active development) reduces memory usage significantly by better managing memory fragmentation. Changing to a statically built fwup, along with reducing the packages we install, helps reduce the final docker image size from _**619MB**_ to _**293MB**_. I've also tweaked the Erlang alloc settings for the binary and eheap allocs, which came from various recommendations to reduce memory fragmentation. --------- Co-authored-by: Nate Shoemaker <[email protected]>
1 parent 1075b77 commit 02971dd

File tree

3 files changed

+85
-16
lines changed

3 files changed

+85
-16
lines changed

.cspell.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
}
1212
],
1313
"dictionaries": [
14-
"cpp",
14+
"cpp",
1515
"elixir",
1616
"en-gb",
1717
"fhunleth-cspell-dictionary",
@@ -20,10 +20,13 @@
2020
],
2121
"ignorePaths": [
2222
"**/*.csv",
23+
"docker/*",
24+
"Dockerfile",
2325
"config",
2426
"assets/{node_modules,static}",
2527
"mix.exs",
2628
"priv",
29+
"rel",
2730
"test"
2831
],
2932
"words": [

Dockerfile

Lines changed: 77 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ ARG RUNNER_IMAGE="ubuntu:${DISTRO}"
88
ARG DEBIAN_FRONTEND=noninteractive
99

1010
###
11-
### First Stage - Fetch deps for building web assets
11+
### Fetch deps for building web assets
1212
###
13-
FROM ${BUILDER_IMAGE} as deps
13+
FROM ${BUILDER_IMAGE} AS deps
1414

1515
ENV MIX_ENV=prod
1616

@@ -24,9 +24,9 @@ RUN mix deps.get --only $MIX_ENV
2424

2525

2626
###
27-
### Second Stage - Build web assets
27+
### Build web assets
2828
###
29-
FROM node:${NODE_VERSION} as assets
29+
FROM node:${NODE_VERSION} AS assets
3030

3131
RUN mkdir -p /priv/static
3232

@@ -42,13 +42,14 @@ RUN npm ci && npm cache clean --force && npm run deploy
4242

4343

4444
###
45-
### Third Stage - Building the Release
45+
### Build the NervesHub release
4646
###
47-
FROM ${BUILDER_IMAGE} as build
47+
FROM ${BUILDER_IMAGE} AS build
4848

4949
# install dependencies
50-
RUN apt-get update -y && apt-get install -y build-essential git ca-certificates curl gnupg \
51-
&& apt-get clean && rm -f /var/lib/apt/lists/*_*
50+
RUN apt-get update -y && apt-get install -y build-essential git ca-certificates curl gnupg && \
51+
apt-get clean && \
52+
rm -f /var/lib/apt/lists/*_*
5253

5354
WORKDIR /build
5455

@@ -95,25 +96,85 @@ COPY rel rel
9596
RUN mix release
9697

9798

99+
###
100+
### Build a static FWUP
101+
###
102+
103+
FROM ${RUNNER_IMAGE} AS fwup
104+
105+
RUN apt-get update -y && \
106+
apt-get upgrade -y && \
107+
apt-get install -y git curl build-essential autoconf pkg-config libtool mtools unzip zip help2man libconfuse-dev libarchive-dev xdelta3 dosfstools
108+
109+
RUN git clone https://github.com/fwup-home/fwup /tmp/fwup
110+
111+
WORKDIR /tmp/fwup
112+
113+
RUN git checkout v1.13.2 && \
114+
./scripts/download_deps.sh && \
115+
./scripts/build_deps.sh && \
116+
./autogen.sh && \
117+
PKG_CONFIG_PATH=$PWD/build/host/deps/usr/lib/pkgconfig ./configure --enable-shared=no && \
118+
make && \
119+
make check && \
120+
make install
121+
122+
123+
###
124+
### Build jemalloc - GCC 14
125+
###
126+
127+
FROM ${RUNNER_IMAGE} AS jemalloc
128+
129+
RUN apt-get update -y && \
130+
apt-get upgrade -y && \
131+
apt-get install -y git autoconf cmake make software-properties-common && \
132+
add-apt-repository ppa:ubuntu-toolchain-r/ppa -y && \
133+
apt-get update -y && \
134+
apt-get install -y gcc-14 g++-14 && \
135+
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-14 14 --slave /usr/bin/g++ g++ /usr/bin/g++-14
136+
137+
# Build the latest jemalloc
138+
139+
RUN git clone https://github.com/facebook/jemalloc /tmp/jemalloc
140+
141+
WORKDIR /tmp/jemalloc
142+
143+
RUN autoconf && \
144+
./configure && \
145+
make && \
146+
make install
147+
148+
98149
###
99150
### Last Stage - Setup the Runtime Environment
100151
###
101152

102153
FROM ${RUNNER_IMAGE} AS app
103154

104155
RUN apt-get update -y \
105-
&& apt-get install -y libstdc++6 openssl libncurses6 locales bash openssl curl python3 python3-pip jq xdelta3 zip unzip wget \
106-
&& wget https://github.com/fwup-home/fwup/releases/download/v1.13.2/fwup_1.13.2_amd64.deb \
107-
&& dpkg -i fwup_1.13.2_amd64.deb && rm fwup_1.13.2_amd64.deb \
108-
&& apt-get clean && rm -rf /var/lib/apt/lists/*
156+
&& apt-get install -y openssl ca-certificates locales bash xdelta3
157+
158+
# Clean up build dependencies and temporary files
159+
RUN apt-get autoremove -y && \
160+
apt-get clean && \
161+
rm -rf /var/lib/apt/lists/*
109162

110163
# Set the locale
111164
RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && locale-gen
112165

113-
ENV LANG en_US.UTF-8
114-
ENV LANGUAGE en_US:en
115-
ENV LC_ALL en_US.UTF-8
166+
ENV LANG=en_US.UTF-8
167+
ENV LANGUAGE=en_US:en
168+
ENV LC_ALL=en_US.UTF-8
169+
170+
# Use jemalloc for memory allocation
171+
COPY --from=jemalloc /usr/local/lib/libjemalloc.so.2 /usr/local/lib/libjemalloc.so.2
172+
ENV LD_PRELOAD=/usr/local/lib/libjemalloc.so.2
116173

174+
# Copy over the statically built fwup
175+
COPY --from=fwup /usr/local/bin/fwup /usr/local/bin/fwup
176+
177+
# Copy over NervesHub
117178
WORKDIR /app
118179

119180
COPY --from=build /build/_build/prod/rel/nerves_hub ./
@@ -124,4 +185,5 @@ ENV SECRET_KEY_BASE=nokey
124185
ENV PORT=4000
125186

126187
ENTRYPOINT ["bin/nerves_hub"]
188+
127189
CMD ["start"]

rel/vm.args.eex

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,7 @@
99

1010
## Tweak GC to run more often
1111
##-env ERL_FULLSWEEP_AFTER 10
12+
13+
## Use "address order best fit" for binary_alloc, and eheap_alloc
14+
+MBas aobf
15+
+MHas aobf

0 commit comments

Comments
 (0)