Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x/tools/gopls: memory issues / multiple instances of gopls running while using neovim/vim-go/coc.vim #41998

Open
vcavallo opened this issue Oct 15, 2020 · 6 comments
Labels

Comments

@vcavallo
Copy link

@vcavallo vcavallo commented Oct 15, 2020

What version of Go are you using (go version)?

$ go version
go version go1.14.9 linux/amd64

Does this issue reproduce with the latest release?

Yes.

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN="/home/vcavallo/go/bin"
GOCACHE="/home/vcavallo/.cache/go-build"
GOENV="/home/vcavallo/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/vcavallo/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build484302687=/tmp/go-build -gno-record-gcc-switches"

What did you do?

Opened a large, module-based project from its root folder (where there are go.mod and go.sum files), started editing files, memory usage skyrockets and system begins freezing hard.

Using:
(from :CocInfo within NeoVim)

vim version: NVIM v0.4.4
node version: v12.17.0
coc.nvim version: 0.0.79-f176d09dc9
term: xterm-256color
platform: linux
## Output channel: languageserver.golang

[Info  - 12:19:59 PM] 2020/10/15 12:19:59 Build info
----------
golang.org/x/tools/gopls 0.4.4
    golang.org/x/tools/gopls@v0.4.4 h1:8djGYsaZ0ByP0vaXg4T+mnyfDcHpWKSZ+tpQSGv9ahk=
    github.com/BurntSushi/toml@v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
    github.com/google/go-cmp@v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=
    github.com/sergi/go-diff@v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
    golang.org/x/mod@v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
    golang.org/x/sync@v0.0.0-20200625203802-6e8e738ad208 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA=
    golang.org/x/tools@v0.0.0-20200729181040-64cdafbe085c h1:jLQLIAedRoS9I2Py7l/ZAGGzUxLFsdg42JXEpS/a+ow=
    golang.org/x/xerrors@v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
    honnef.co/go/tools@v0.0.1-2020.1.4 h1:UoveltGrhghAA7ePc+e+QYDHXrBps2PqFZiHkGR/xK8=
    mvdan.cc/gofumpt@v0.0.0-20200709182408-4fd085cb6d5f h1:gi7cb8HTDZ6q8VqsUpkdoFi3vxwHMneQ6+Q5Ap5hjPE=
    mvdan.cc/xurls/v2@v2.2.0 h1:NSZPykBXJFCetGZykLAxaL6SIpvbVy/UFEniIfHAa8A=

Go info
-------
go version go1.14.9 linux/amd64

memory zips from tmp this morning:

gopls.27845-2GiB-nonames.zip
gopls.15708-2GiB-nonames.zip
gopls.15708-1GiB-nonames.zip
gopls.27845-1GiB-nonames.zip

gopls-hog

What did you expect to see?

normal editor usage

What did you see instead?

out of memory issues on overall OS.

@gopherbot gopherbot added this to the Unreleased milestone Oct 15, 2020
@heschik
Copy link
Contributor

@heschik heschik commented Oct 15, 2020

Sorry, but a couple gigs of usage is not totally out of line with expectations, and I don't see anything obviously wrong in the memory dumps. I think you'd have more luck figuring out why you have 3 copies of gopls running.

cc @findleyr for what seems to be a vim thing based on the -remote usage.

@findleyr
Copy link
Contributor

@findleyr findleyr commented Oct 15, 2020

Hmm, I see 9 gopls instances actually: 2 daemons, 3 'sidecars', and 4 'forwarders'. Were you by chance playing around with different configuration? Do you have multiple neovim processes running?

I'm guessing the multiple daemons are due to https://golang.org/issue/41266, unfortunately. Neovim users may be better off not using a daemon until that is resolved (or using a manually started daemon).

Can you please try killing all the gopls instances to test if you experience the same symptoms in a fresh session?

@vcavallo
Copy link
Author

@vcavallo vcavallo commented Oct 15, 2020

I only have one neovim process running, but as you suspect @findleyr, I have been playing with settings and may have both vim-go and coc.vim using gopls simultaneously?

Immediately after a sudo killall gopls I get two gopls commands, two gopls -remote=auto and one gopls serve -listen unix automatically starting up (watching in htop).

After changing settings to add -remote=auto to the CocConfig here:

"languageserver": {
   "golang": {
     "command": "gopls",
     "args": ["-remote=auto"],
     "rootPatterns": ["go.mod", ".vim/", ".config/nvim/", ".git/", ".hg/"],
     "filetypes": ["go"]
   }
 }

And disabling gopls in vim-go (let g:go_gopls_enabled = 0), things are quite a bit better. I haven't yet started retracing steps and trying one at a time to see what's solving it, though.


I've updated the issue name to be less accusatory of gopls :) looking to be more of an issue with editor integration (unsurprisingly, i'm sure).

@vcavallo vcavallo changed the title x/tools/gopls: Using all of system memory x/tools/gopls: memory issues / multiple instances of gopls running while using neovim/vim-go/coc.vim Oct 15, 2020
@findleyr
Copy link
Contributor

@findleyr findleyr commented Oct 15, 2020

I'm glad to hear that things are somewhat better, but it sounds like there are still some improvements to be made.

First, what is your motivation for using multiple plugins with a single editor process? When using gopls, each will have their own LSP session and will send text updates independently. I'd expect this to cause problems like duplicate diagnostics, etc.

Second, which version of vim-go are you using? I'd be interested to know if vim-go is using -remote=auto (which is the default only in recent versions), and if it is connecting to the same daemon. If vim-go uses a different gopls binary or different go binary, or has a different value for $TMPDIR, it will start its own daemon.

If it is intentional to have multiple gopls sessions for a single neovim process, there are things we can try that could significantly increase the amount of shared cache between these sessions, provided they are both on the same daemon (for example, in https://golang.org/cl/260737 I added an experiment that modifies our cache key for type information in such a way that it should now be shared when multiple plugins have gopls sessions).

Let me know. This is an interesting use-case, and I'd greatly appreciate any follow-up you're able to do here.

@stamblerre stamblerre removed this from the Unreleased milestone Oct 16, 2020
@vcavallo
Copy link
Author

@vcavallo vcavallo commented Oct 16, 2020

@findleyr thanks!

what is your motivation for using multiple plugins with a single editor process?

Partially an accident of history, partially intentional: I started with vim-go (on standard vim) last year and liked it. I recently learned about NeoVim and COC - which provides a lot of great highlighting and code completion that vim-go doesn't provide (as far as I know). I like a lot of the features that vim-go does provide - like triggering tests, formatting, linting I've already configured, etc - so I'm keeping it around for now for that reason.

I'd expect this to cause problems like duplicate diagnostics, etc.

Indeed, I ran across this (getting double entries in the COC highlight bubbles). My current configuration seems to be avoiding that issue now.

Second, which version of vim-go are you using?

I believe I'm on 1.24, the latest release.

[...] and if it is connecting to the same daemon [...]

have you seen this? https://github.com/ericwq/golangIDE/blob/master/shared-gopls-daemon.md not sure if that's helpful here.

I've changed things a bit since I last wrote here, but the results still seem positive.

I have the following coc-settings.json (for COC.vim and coc-go)

{
   // [...]
  "go.goplsArgs": ["-remote=auto", "-logfile", "/tmp/gopls.log"],
  "go.goplsPath": "/home/vcavallo/go/bin/gopls",
   // [...]
}

And I've removed the golang languageserver block, which I think means coc-go (which I've since installed) handles the connection to gopls now - yet another wrinkle, but one that seems to be helping! (from here)

So hopefully both vim-go and coc-go are using gopls properly with -remote=auto and using the same binary. But to be honest, once things started working well enough I stopped troubleshooting and got back to work.
If you want to test things out deeper on my system I'm happy to work out some method of doing so with you.

If it is intentional to have multiple gopls sessions for a single neovim process

Nope. I'd like the option to have arbitrary vim/neovim plugins and not have to worry about how many gopls sessions they're starting up. But I realize that will likely ultimately be a plugin config responsibility and not gopls's problem.

@findleyr
Copy link
Contributor

@findleyr findleyr commented Oct 16, 2020

Thanks for the update, it's useful to hear the process that led you into this state. Getting daemon discovery right is a fundamentally hard problem, because in some cases we want to have multiple daemons (for example, if there's a version mismatch in the gopls binary). I just want to reduce the friction for plugins to find the right daemon. -remote=auto was supposed to do that, but the changing TMPDIR is a source of friction I wasn't expecting.

I'll leave this open as a meta-issue tracking this problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
5 participants
You can’t perform that action at this time.