This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-09-05
Channels
- # announcements (2)
- # babashka (19)
- # beginners (14)
- # biff (10)
- # calva (23)
- # clojure (49)
- # clojure-europe (15)
- # clojure-nl (3)
- # clojure-norway (25)
- # clojure-seattle (1)
- # clojure-uk (4)
- # clojurescript (7)
- # data-science (6)
- # datahike (3)
- # datomic (1)
- # emacs (13)
- # events (2)
- # fulcro (3)
- # graalvm (13)
- # hyperfiddle (32)
- # leiningen (4)
- # lsp (38)
- # malli (1)
- # missionary (34)
- # nbb (28)
- # off-topic (42)
- # other-languages (5)
- # portal (8)
- # practicalli (1)
- # re-frame (3)
- # releases (1)
- # ring (7)
- # shadow-cljs (13)
- # sql (3)
Hi all, I'm trying to figure out why my clojure-lsp
process is taking up 6.67GB of memories at work. Can anyone give me the high-level mental model of what's being loaded into memory by clojure-lsp
? I want some more ideas to help me navigate the clojure-lsp
source code.
The project I'm working on is a monorepo and uses a mixture of lein-monolith and deps.edn to manage the sub-project dependencies. My current setup has a similar :project-specs
as below to tell clojure-lsp
all the classpaths to find the Clojure/Script source files:
{:project-specs [{:project-path "project.clj"
:classpath-cmd ["lein" "with-all" "classpath"]}
{:project-path "deps.edn"
:classpath-cmd ["clojure" "-A:dev" "-Spath"]}]}
And my mono repo has the shape of:
mono-repo-root/
project.clj
lein-monolith-project-1/
project.clj
src/
lein-monolith-project-2/
project.clj
src/
deps.edn
tools-deps-project-1/
deps.edn
src/
tools-deps-project-2/
deps.edn
src/
And the clojure-lsp version info is:
$ clojure-lsp --version
clojure-lsp 2023.08-06-00.28.06
clj-kondo 2023.07.14-SNAPSHOT
but never saw 6gb, actually there is a limit of 2GB per clojure-lsp process :thinking_face:
Yeah that got me confuses too. This is what it looks like at the moment.
I assumed those jvm-opts only applies to the compilation of the clojure-lsp
graalvm native image and not baked into the native image at runtime. I don’t have enough experiences with graalvm to be sure tho. :thinking_face:
Would be nice to run a JMC to profile the memory, we can probably find mem per improvements somewhere
Would be nice to plug the repl on the running clojure-lsp and check how much is the size of clojure-lsp.db/db atom
Kk thanks that’s where I’ll start! Thank you! Also FYI I just found this: https://www.graalvm.org/latest/reference-manual/native-image/optimizations-and-performance/MemoryManagement/#java-heap-size - seems like the option to bake the memory limit into the native image is -R:MaxHeapSize
Oh, that's quite interesting, but I wonder if the process would just stop working when reaches the limit
Yeah I wouldn’t change that setting without testing it thoroughly. 😛 Just want to share what I found so far.
With a JVM one we can use https://github.com/clojure-goes-fast/clj-memory-meter as well
Yeah I’m getting OOM exception so far with the debug-cli executable. It’s okay I’ll bump the Xmx setting to get it going. Because my project is pretty complex, I’d like to inspect the db atom to see if I happen to be loading redundant analysis for my project.
Yeah, also, check the .lsp/.cache/db.transit.json which is a big part of the db that goes in the atom
Oh mine is 276MB at this point.
Would you help me understand what goes into this cache file?
basically https://github.com/clojure-lsp/clojure-lsp/blob/57d39a0c31b733f5c71d7f33265cad39e23bed6b/lib/src/clojure_lsp/startup.clj#L161-L167, but probably :analysis
is the huge map there, it contains all clj-kondo analysis of the project and external deps
load that into mem was never a issue, but your case seems a little bit corner case since it's a huge project, maybe for that case we may want to have a flag to make clojure-lsp have less things on db :thinking_face:
i'd play with these values https://github.com/clojure-lsp/clojure-lsp/blob/57d39a0c31b733f5c71d7f33265cad39e23bed6b/lib/src/clojure_lsp/kondo.clj#L254-L276 in a local clojure-lsp JVM, to see if there is something that decreases the size of the db by a lot
Kk thank you 🙇 I’ll give it a try! 🙏
@U7PQH43PS Were you successful? My db.transit.json is 900mb and ram consumption is huge.
@UBRV1HXPD could you try
.lsp/config.edn
{:java nil}
I'm understanding how performance degrades with java features@UKFSJSM38
The effect is there, but not big. It’s hard to say. When I open Emacs, load a project, and start lsp, and wait, it once consumed 5.90GB, and another time at 5.53GB. When I set it to {:java nil}
, RAM consumption was 4.9GB and 5.3GB.
while 2023.08.06-00.28.06 consumes less memory than 2023.07.01-22.35.41 (with that version my project consumed ~7GB) i have got a feeling that a new version leads to new bugs (flymake, xref got timeout) but it is really hard to reproduce it and do some testing as I have experienced this after 3 hours working on project and I didn’t have time to do some debugging. But that is another topic (i still need to reproduce to be sure) :-)
I think the 2gb limit is not working for graalm native images otherwise you would get Out of memory errors
I want to focus on some perf improvements like that until the end of the year, but not a promisse we will have huge improvements in there, at least options to disable features maybe
@UKFSJSM38, huge thanks for the https://github.com/clojure-lsp/clojure-lsp/issues/1700. The memory usages for my use case is down from 6GB to 3GB. This is a significant improvement for me. Thank you thank you 🎉 🙏
That's really good to hear @U7PQH43PS, it's important to know how significant those improvements are :)
I agree. These improvements are really significant. With the last version I got the same results like @U7PQH43PS on Macbook M1PRO.