Один з найпростіших способів оптимізувати використання пам'яті програмою є використання jemalloc—альтернативної імплементації malloc
.
malloc
—це стандартна функція виділення пам'яті в С. Вона використовується всередині MRI та інтерпретаторів інших мов. Використання jemalloc
прозоре—підміняється імплементація функції і програми працюють як і раніше, не підозрюючи що пам'ять тепер використовується більш ефективно. Поверхневі деталі імплементації ви можете почитати на StackOverflow, там ж є посилання на більш детальні пояснення.
Цей метод згадується практично у всіх гайдах по оптимізації Rails-додатків. Коли я тільки зробив donate1024 то розмістив його на серверах з 256 мегабайтами пам'яті. З часом коли функцій та користувачів додалось, почав спрацьовувати oom killer. Тоді я видав серверу ще 256 мегабайт і забув про проблему.
Нещодавно я займався перформерс оптимізаціями проекту і згадав про jemalloc
. Навіщо платити більше? Тому я швиденько знайшов як додати його в Alpine Linux який в мене використовується як базовий образ, все зробив і задеплоїв:
FROM ruby:3.1.2-alpine AS jemalloc_builder
RUN apk add build-base
ARG JEMALLOC_VERSION=5.3.0
RUN wget -O - https://github.com/jemalloc/jemalloc/releases/download/${JEMALLOC_VERSION}/jemalloc-${JEMALLOC_VERSION}.tar.bz2 | tar -xj && \
cd jemalloc-${JEMALLOC_VERSION} && \
./configure && \
make && \
make install
FROM ruby:3.1.2-alpine
COPY --from=jemalloc_builder /usr/local/lib/libjemalloc.so.2 /usr/local/lib/
ENV LD_PRELOAD=/usr/local/lib/libjemalloc.so.2
Для Alpine потрібно компілювати лібу, бо готовий пакет з якихось причин перестали підтримувати.
В результаті використання пам'яті знизилось з ~230 мегабайт до ~180 чого вистачає для того щоб апка спокійно жила на інстансі з 256 мегабайтами. Таку ж оптимізацію я зробив для проекта adopt.ua де ефект був ще кращим: з ~270 мегабайт до ~170.
Для інших інтерпретаторів цей трюк по ідеї теж має працювати. Шукайте рішення для своєї платформи.
Сподобалось? Долучайтеся до мого телеграм каналу: https://t.me/full_of_hatred