Zulip Chat Archive
Stream: lean4
Topic: Memory increase in loops.
Joseph Tooby-Smith (Sep 03 2024 at 10:06):
On running the following mwe:
import Batteries.Lean.HashSet
import Lean
open Lean Elab System
unsafe def processFileHeader (file : FilePath) : IO Unit := do
searchPathRef.set compile_time_search_path%
let fileContent ← IO.FS.readFile file
enableInitializersExecution
let inputCtx := Parser.mkInputContext fileContent file.toString
let (header, parserState, messages) ← Parser.parseHeader inputCtx
let (env, messages) ← processHeader header {} messages inputCtx
-- Other code to go here.
pure ()
unsafe def main : IO Unit := do
let file := ".lake/packages/mathlib/Mathlib/Algebra/AddConstMap/Basic.lean"
for n in List.range 100 do
println! "{n}"
processFileHeader file
each step in the for
loop in main
leads to an increase in memory. It seems like the variables env
and messages
etc are held onto once the function processFileHeader
is complete for each iteration. Is this the case? Is there a way to clear these variables to ensure they are not kept between iterations and memory doesn't explode.
(The code in processFileHeader
is based on code from here)
Joseph Tooby-Smith (Sep 03 2024 at 13:50):
The memory still explodes with the more functional approach where main
above is replaced with:
unsafe def main : IO Unit := do
let file := ".lake/packages/mathlib/Mathlib/Algebra/AddConstMap/Basic.lean"
(List.range 100).forM (fun _ => processFileHeader file)
Henrik Böving (Sep 03 2024 at 13:58):
env
does not get free-d because it contains mmap
-ed data. So in order to free env
you need to free all of env
at once. However that requires that not a single reference into env
exists anymore which is an invariant that you have to ensure. There is unsafe functions like docs#Lean.withImportModules that do free the environment they create and are safe to call under the assumption that no references to objects in env exist anymore. You can imitate what they are doing under the hood to free and env if you want.
Joseph Tooby-Smith (Sep 03 2024 at 18:35):
Thanks @Henrik Böving ! Until I understand exactly how to do this, I'm going to follow the same workaround as here, which is to use IO.Process.run
to call another file containing processFileHeader
.
Last updated: May 02 2025 at 03:31 UTC