Cap glibc malloc arenas to keep non-Go RSS bounded (closes #23)
check / check (push) Failing after 1s
check / check (push) Failing after 1s
After the earlier memory work, SQLite's live heap is bounded but process RSS still climbed about 70 MiB/min, nearly all anonymous and outside the Go runtime and outside SQLite's own accounting, without any SQLITE_NOMEM. The cause is glibc: the SQLite C library allocates and frees millions of small page-cache chunks from many threads, and glibc keeps each arena's freed chunks resident. With arenas uncapped it creates up to eight per core, so on a large host RSS grows with the core count. Set MALLOC_ARENA_MAX=2 in the image to bound the retained memory. Writes are already serialized, so the two-arena cap costs no throughput. Update the README Memory section. Model: opus-4-8
This commit is contained in:
@@ -83,6 +83,14 @@ ENV XDG_DATA_HOME=/var/lib
|
||||
# XDG_DATA_HOME above.
|
||||
ENV GOMEMLIMIT=1536MiB
|
||||
|
||||
# Cap glibc's malloc arenas. The SQLite C library allocates and frees millions
|
||||
# of small page-cache chunks from many threads; glibc otherwise creates up to
|
||||
# eight arenas per core (hundreds on a large host) and keeps each arena's freed
|
||||
# chunks resident, so process RSS climbs far above SQLite's live heap and never
|
||||
# comes back down. Two arenas keep that retained memory bounded; database writes
|
||||
# are already serialized, so the lost allocator concurrency costs nothing here.
|
||||
ENV MALLOC_ARENA_MAX=2
|
||||
|
||||
# Expose HTTP port
|
||||
EXPOSE 8080
|
||||
|
||||
|
||||
Reference in New Issue
Block a user