cairo: bug: Possible memory leak in cairo-language-server

Bug Report

Cairo version: v2.2.0

Current behavior:

Cairo-LS memory usage seem to not decrease with removal of cairo code, leading to unreasonably high volumes of consumed memory.

Expected behavior:

Cairo-LS memory usage stays at reasonable levels.

Steps to reproduce:

  1. Install the latest version of scarb (0.7.0)
  2. Clone this repository: https://github.com/carbonable-labs/cairo-erc-2981 and open VSCode
  3. Open a task manager on the side and the Output tab in VSC and track scarb-cairo-language-server
  4. Open the file at src/components/ercc2981/interface.cairo and leave scarb sync
  5. Create a new empty interface at the end of the file:
#[starknet::interface]
trait TestTrait<TContractState> {
}

Note: The Memory usage must be around 800Mo

  1. Add a new method in the interface and observe the memory usage increasing by 3-10Mo per method added, such as:

Memory: 798.6Mo

#[starknet::interface]
trait TestTrait<TContractState> {
    fn test01(self: @TContractState) -> u256;
}

Memory: 802.3Mo

#[starknet::interface]
trait TestTrait<TContractState> {
    fn test01(self: @TContractState) -> u256;
    fn test02(self: @TContractState) -> u256;
}

Memory: 806.5Mo

etc.

Note: Removing the previous methods doesn’t release memory (it increase but not significantly) Note: The Cairo-Language-Server Ouput tab doesn’t log anything while adding code. Note: This example shows an reasonable increase of the memory however while writing a whole implementation use significant amount of code, it results in reaching 10Go in few minutes.

Other information:

Originally reported in https://github.com/software-mansion/scarb/issues/624 by https://github.com/Bal7hazar, reposting here as Scarb does not seem to ba causing this issue.

About this issue

  • Original URL
  • State: closed
  • Created 10 months ago
  • Reactions: 3
  • Comments: 20 (4 by maintainers)

Most upvoted comments

the LRU thing is probably a better chance of working generally - when i looked into it - it wasn’t too easy to use. It isn’t about the number of nodes per AST - as there’s no reason for this to affect anything - as the issue is not release the old nodes, not simply having too many of these.

@mkaput thanks for the pointer about Rust Analyzer using salsa as well. Did some more digging and this is what I found.

Rust Analyzer also takes up quite a bit of memory (see screenshot). The 2.2g instance is actually a pretty big codebase compared to Cairo LSP reaching the same level of memory with a much smaller repo image

Found this RFC which points to how rust-analyzer uses salsa LRU capacity to limit the memory used while there seems to be no usage of LRU capacity in the cairo-language-server. This seems like a good potential solution to limit memory usage.

I also experimented with upgrading salsa from 0.16.1 to 0.17-0.pre.2 but the effect seems to be negative on the cairo-erc-2981 repo. 0.16.1: ~800MB 0.17-0.pre.2: ~1.5GB

32 GB after a day’s work

Screenshot 2023-11-15 at 18 23 54
  1. It is a private query - it provides info for 8 other queries.
  2. Why would that reduce memory? also how does handling of .toml changes should work now?

On an unrelated note - probably found an additional way to vastly remove the amount of calculations done caused by files generated from plugins - would probably reduce the effect of the problem by a lot.

I also have some questions.

1.After a file is changed, if there are a large number of updates in a short period of time, how do you handle the old syntax tree corresponding to each update of the file, and how do you generate a new syntax tree? Also, due to asynchronous operations, Is that possible the older updated content could be processed after the newly updated content?

2.Based on question 1, we noticed that even if we add an empty line, the memory consumption will increase, and then delete the empty line immediately, the memory will not decrease. I feel that if I know the answer to question 1, it will greatly help us locate the problem.

Hmm, Rust Analyzer is using salsa 0.17-0.pre.2. Perhaps it has some changes that enable RA to not exhibit this problem? Or maybe does RA do something that is not actually causing Salsa to allocate so much?

https://github.com/rust-lang/rust-analyzer/blob/45136511a5b4f6b216aba371f541fb2251868c2b/crates/base-db/Cargo.toml#L15