lua-language-server icon indicating copy to clipboard operation
lua-language-server copied to clipboard

大工程使用了极多的内存

Open lyzardiar opened this issue 3 years ago • 22 comments

How are you using the lua-language-server?

Visual Studio Code Extension (sumneko.lua)

Which OS are you using?

Windows

What is the issue affecting?

Other

Expected Behaviour

工作区诊断完成后

Actual Behaviour

接近5000个文件加载完成后, 内存占用5G左右

Reproduction steps

  1. Go to
  2. Click
  3. See error

Additional Notes

No response

Log File

No response

lyzardiar avatar Aug 15 '22 03:08 lyzardiar

目前确实是一个文件1M左右内存,以后有机会看看怎么优化。

sumneko avatar Aug 15 '22 18:08 sumneko

这个大小是固定的吗? 还是某个功能占用的特别多? 我可以先关掉占用内存高的功能

lyzardiar avatar Aug 16 '22 06:08 lyzardiar

固定的

sumneko avatar Aug 16 '22 06:08 sumneko

固定的

如果文件大小固定的话,是不是生成的提示都写到同一个文件更好,减少文件数量同时降低内存消耗

linoodb avatar Aug 16 '22 08:08 linoodb

应该和文件大小成正比,大部分情况下1个文件平均消耗1M内存。消耗的内存主要是解析文件以及对解析结果进行预处理和缓存导致的。

sumneko avatar Aug 16 '22 08:08 sumneko

经过一些简单测试,大部分内存占用都来自解析文件生成的语法树,因为语法树格式是lua表形式,因此内存占用确实会很高,例如lua代码 {} 会被解析成 { type = 'table', start = 0, finish = 2 } 。前者只有2个字节大小,但生成的lua表有200多字节,放大了100倍。可能需要重新设计语法树结构才能解决这个问题。

sumneko avatar Aug 16 '22 09:08 sumneko

经过一些简单测试,大部分内存占用都来自解析文件生成的语法树,因为语法树格式是lua表形式,因此内存占用确实会很高,例如lua代码 {} 会被解析成 { type = 'table', start = 0, finish = 2 } 。前者只有2个字节大小,但生成的lua表有200多字节内存占用,放大了100倍。可能需要重新设计语法树结构才能解决这个问题。

sumneko avatar Aug 16 '22 09:08 sumneko

这样治标不治本,可以试着让一部分不重要的语法树不在内存中,实际上5k文件里面常用的就几十几百,大部分解析的结果只需要作为api提示。所以可以进一步设定长期工作目录,其他的不重要的目录,不缓存语法树,甚至文件内容都不缓存。

CppCXY avatar Aug 16 '22 11:08 CppCXY

这样治标不治本,可以试着让一部分不重要的语法树不在内存中,实际上5k文件里面常用的就几十几百,大部分解析的结果只需要作为api提示。所以可以进一步设定长期工作目录,其他的不重要的目录,不缓存语法树,甚至文件内容都不缓存。

我目前会将语义和语法树部分节点互相绑定,因此只有当一个文件完全没有使用任何全局变量以及 ---@class---@type 时我才能安全释放这个文件的内存。 不过想了想,这年头内存又不值钱,5000个文件的巨大工作目录总是要付出一些代价的,请自己尝试忽略掉无用的文件或是加内存吧。

sumneko avatar Aug 16 '22 16:08 sumneko

5G内存也算多吗

actboy168 avatar Aug 17 '22 03:08 actboy168

我加入了一个实验性的功能,可以将未打开的文件的语法树生成到硬盘上而不是内存中,经测试这可以节省大约一半的内存,但是代价是初始化工作目录需要花费较长的时间,我的电脑上测试下来1秒只能编译20个文件。

启用方法是在启动参数中加入 --lazy (VSCode设置为 misc.parameters)。

另外如果你不需要的话可以关闭工作区诊断(将 diagnostics.workspaceDelay 设置为 -1),这也可以节省一半以上的内存。

sumneko avatar Aug 19 '22 19:08 sumneko

问题相同,在公司开发没法控制开发环境的内存配置,希望能优化插件的内存占用。

Nuctori avatar Aug 24 '22 02:08 Nuctori

或许可以利用luac 改造 ldump.c 使用lua原生的语法解析器, 将lua语法树数据提供给插件, c结构体占用内存更少, 解析器速度可以更快。

w4454962 avatar Aug 24 '22 06:08 w4454962

或许可以利用luac 改造 ldump.c 使用lua原生的语法解析器, 将lua语法树数据提供给插件, c结构体占用内存更少, 解析器速度可以更快。

不可能使用原生的,要做也把LuaParser用C重写一遍。两边生成的语法树结构完全不一样。

sumneko avatar Aug 24 '22 06:08 sumneko

还有个办法就是 改成luajit, ast使用的 table 全部用 ffi + struct 来实现 这样也能降低内存 加快速度

w4454962 avatar Aug 24 '22 06:08 w4454962

还有个办法就是 改成luajit, ast使用的 table 全部用 ffi + struct 来实现 这样也能降低内存 加快速度

你这个目的是和重新设计结构一样的,我自己设计一个压缩格式用字节流一样能实现。 LuaJIT一方面我是用的运行时不支持,另一方面JIT本来就是用空间换时间的方案,占用的内存理论上会更多。

sumneko avatar Aug 24 '22 06:08 sumneko

我加入了一个实验性的功能,可以将未打开的文件的语法树生成到硬盘上而不是内存中,经测试这可以节省大约一半的内存,但是代价是初始化工作目录需要花费较长的时间,我的电脑上测试下来1秒只能编译20个文件。

启用方法是在启动参数中加入 --lazy (VSCode设置为 misc.parameters)。

另外如果你不需要的话可以关闭工作区诊断(将 diagnostics.workspaceDelay 设置为 -1),这也可以节省一半以上的内存。

1: --lazy 这个在哪个版本开始生效? 2: 我的电脑上测试下来1秒只能编译20个文件。 我这边是i5-12400, 不使用lazy参数的情况下, 每秒也只能编译10个文件左右

lyzardiar avatar Sep 05 '22 06:09 lyzardiar

3.5.4或3.6.0吧。 你可以先从ci里下载最新的版本尝试一下:https://github.com/sumneko/lua-language-server/actions/runs/2977600473 解压覆盖本地的插件文件即可

sumneko avatar Sep 05 '22 06:09 sumneko

谢谢, 内存确实少了快一半, 就是解析速度有点慢

lyzardiar avatar Sep 06 '22 03:09 lyzardiar

谢谢, 内存确实少了快一半, 就是解析速度有点慢

嗯,所以实用性不高,除非我继续搞个持久性缓存,可以复用你上次启动语言服务时的本地缓存,这样就只有第一次要解析这么久。不过我还是觉得这么复杂的方案换这么点内存不值得,建议你联系你公司的IT帮你加根内存条。

sumneko avatar Sep 06 '22 03:09 sumneko

谢谢, 内存确实少了快一半, 就是解析速度有点慢

嗯,所以实用性不高,除非我继续搞个持久性缓存,可以复用你上次启动语言服务时的本地缓存,这样就只有第一次要解析这么久。不过我还是觉得这么复杂的方案换这么点内存不值得,建议你联系你公司的IT帮你加根内存条。

这个比较难, 因为组里人比较多, 寡而不均最麻烦; 现在只能先用这个方案替代一下. (内存现在也有16G, 系统, 业务, 其他本地软件都需要一部分内存, 开了插件(占用内存6G以上)内存使用率就会到90%以上, 导致系统一卡一卡的)

lyzardiar avatar Sep 08 '22 02:09 lyzardiar

谢谢, 内存确实少了快一半, 就是解析速度有点慢

嗯,所以实用性不高,除非我继续搞个持久性缓存,可以复用你上次启动语言服务时的本地缓存,这样就只有第一次要解析这么久。不过我还是觉得这么复杂的方案换这么点内存不值得,建议你联系你公司的IT帮你加根内存条。

这个比较难, 因为组里人比较多, 寡而不均最麻烦; 现在只能先用这个方案替代一下. (内存现在也有16G, 系统, 业务, 其他本地软件都需要一部分内存, 开了插件(占用内存6G以上)内存使用率就会到90%以上, 导致系统一卡一卡的)

俺也一样

Nuctori avatar Sep 08 '22 11:09 Nuctori

5000个文件。。。。还用lua写啊。。这不换语言?

BreakingLead avatar Apr 14 '23 15:04 BreakingLead

精力有限,暂时不打算进一步关注内存问题。你可以先把工作区诊断关掉试试。

sumneko avatar Apr 24 '23 06:04 sumneko