Yet another question about Julia's high RAM usage

Summary of my current understanding: Julia has a relatively high memory footprint for an interactive language for various reasons: 1) an OpenBLAS implementation that preallocates buffers to accelerate matrix multiplication that cannot be removed from Base, 2) a JIT compiler that interpreted languages don’t use, 3) overheads for modules, types, docstrings, and all the good stuff we need for interactivity. This hasn’t changed much in the last few years, but the upcoming --trim option of juliac is bringing an era of non-interactive AOT compilation where we could potentially remove this overhead for contexts that call for it.

Eyeballing the Windows Task Manager, I checked what the numbers are currently (v1.11.6). In a fresh REPL session started from Windows Powershell:

julia> # typing goes from 157 to 161MB, typical over last few years

julia> using Example # typing creeps up to 166MB

julia> hello(string(domath(2))) # only 2 functions in Example
"Hello, 7"

julia> # 167MB here

julia> hello(domath(10)) # I know this will throw a MethodError
ERROR: MethodError: no method matching hello(::Int64)
...
julia> # jumped to 257MB

(@v1.11) pkg> st
...
julia> # jumped to 386MB

I was really surprised by the massive jumps of ~90MB and ~130MB for seemingly small things like throwing a MethodError or using the Pkg REPL mode to check my environment. This also means that the ~150-200MB estimate for loading the REPL is too low for estimating practical REPL usage even if we stick to the standard library or very small packages. By comparison, Python v3.13.3’s REPL takes a little under 10MB to start, and I could import a dozen standard libraries (I’m assuming Python wrappers of C binaries) to just manage 15MB; throwing errors didn’t change the RAM usage.

Can anybody explain those huge jumps? I know the native code is different and isn’t comparable, but could Julia have a much larger overhead for managing the existence of modules, types, methods, etc?

EDIT: Suspecting platform dependence, so including my versioninfo here.

julia> versioninfo()
Julia Version 1.11.6
Commit 9615af0f26 (2025-07-09 12:58 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: 8 × Intel(R) Core(TM) i7-1065G7 CPU @ 1.30GHz
  WORD_SIZE: 64
  LLVM: libLLVM-16.0.6 (ORCJIT, icelake-client)
Threads: 1 default, 0 interactive, 1 GC (on 8 virtual cores)
3 Likes

I wonder how much of this is allocations of strings during compilation of various error paths. Strings, due to being semantically immutable, don’t get garbage collected as far as I remember. They are also constant propagated, which can cause more allocations, even though the compiler doesn’t actually use that result.

Strings do get GC’d, but code and symbols do not.

There might be something to do about the large memory footprint, but probably not that much. The whole premise of Julia is that RAM is so cheap that we can just make every function generic, monomorphize everything and generate all the custom code on demand.

So yeah, there are all the things you write, but then Julia also makes it hard to make sure there aren’t 50 unnecessary specializations of a bunch of functions.

2 Likes

FYI, I was curious, but I don’t observe those memory jumps on my Windows machine using Julia 1.10.9 from the terminal (not VSCode) - everything stays around 50 MB from using Example to the MethodError.

2 Likes

That’s interesting, I tried 1.10.9 and more or less reproduced the first post with different numbers: 111, 112, 248, 307MB, the jumps being ~140MB and ~60MB instead. Could you elaborate with how you were checking the RAM usage and your versioninfo? Here’s mine for 1.10.9:

julia> versioninfo()
Julia Version 1.10.9
Commit 5595d20a28 (2025-03-10 12:51 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: 8 × Intel(R) Core(TM) i7-1065G7 CPU @ 1.30GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-15.0.7 (ORCJIT, icelake-client)
Threads: 1 default, 0 interactive, 1 GC (on 8 virtual cores)

That’s nothing. For me, just starting Julia raises memory to almost 1 GB. Middle process in the attached fig. The other two are due to two instances of VSC.
I only have Revise in my startup.