Fork me on GitHub
#lsp
<
2023-09-05
>
Daw-Ran Liou20:09:41

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

ericdallo21:09:12

your mono-repo and config looks correct

ericdallo21:09:28

but never saw 6gb, actually there is a limit of 2GB per clojure-lsp process :thinking_face:

Daw-Ran Liou21:09:31

Yeah that got me confuses too. This is what it looks like at the moment.

Daw-Ran Liou22:09:04

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:

ericdallo22:09:33

That's interesting, first time I see that with more than 2GB

ericdallo22:09:48

Yeah, I never managed to test that, but seems like you are correct

ericdallo22:09:16

Would be nice to run a JMC to profile the memory, we can probably find mem per improvements somewhere

ericdallo22:09:04

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

❤️ 2
💡 2
👍 2
ericdallo22:09:17

It keeps all the analysis of the project

Daw-Ran Liou22:09:31

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

ericdallo22:09:19

Oh, that's quite interesting, but I wonder if the process would just stop working when reaches the limit

ericdallo22:09:14

Ah, the repl plug will only work with a JVM clojure-lsp not a Graal one

Daw-Ran Liou22:09:16

Yeah I wouldn’t change that setting without testing it thoroughly. 😛 Just want to share what I found so far.

ericdallo22:09:58

To generate a JVM one just clone the repo and run bb debug-cli

ericdallo22:09:23

But I suppose you should get OutOfMem exceptions since the limit is 2GB

Daw-Ran Liou22:09:34

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.

ericdallo22:09:00

Yeah, also, check the .lsp/.cache/db.transit.json which is a big part of the db that goes in the atom

ericdallo22:09:38

If that is huge, (more than 100mb) probably that's the problem

Daw-Ran Liou22:09:21

Oh mine is 276MB at this point.

Daw-Ran Liou22:09:06

Would you help me understand what goes into this cache file?

ericdallo22:09:29

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

ericdallo22:09:34

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:

ericdallo22:09:27

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

Daw-Ran Liou22:09:24

Kk thank you 🙇 I’ll give it a try! 🙏

Akiz18:10:05

@U7PQH43PS Were you successful? My db.transit.json is 900mb and ram consumption is huge.

ericdallo18:10:27

@UBRV1HXPD could you try .lsp/config.edn

{:java nil} 
I'm understanding how performance degrades with java features

Akiz19:10:12

@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) :-)

ericdallo19:10:59

yeah so maybe it's related with your clojure code being the biggest part indeed

👍 1
Akiz19:10:09

the 2gb limit works in what cases?

ericdallo19:10:49

I think the 2gb limit is not working for graalm native images otherwise you would get Out of memory errors

ericdallo19:10:16

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

👍 1
Akiz19:10:41

Ah, you already discussed it here. Sorry to ask again. Good luck!

👍 1
Daw-Ran Liou18:11:17

@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 🎉 🙏

🎊 1
ericdallo18:11:02

That's really good to hear @U7PQH43PS, it's important to know how significant those improvements are :)

❤️ 2
🙏 1
🎉 1
Akiz07:11:36

I agree. These improvements are really significant. With the last version I got the same results like @U7PQH43PS on Macbook M1PRO.

gratitude 2
❤️ 1
🎉 1