Golangci-lint: Increased memory usage in 1.24.0 causing out-of-memory

Created on 16 Mar 2020  路  16Comments  路  Source: golangci/golangci-lint

It seems that after upgrading golangci-lint for my project to 1.24.0, Travis CI is no longer able to lint the project, as it fails with out-of-memory errors: https://travis-ci.org/github/flexkube/libflexkube/jobs/662847029#L1086

After reverting the same PR to 1.23.8, linting passes: https://travis-ci.org/github/flexkube/libflexkube/jobs/662848310?utm_medium=notification&utm_source=github_status.

PR affected by the issue: https://github.com/flexkube/libflexkube/pull/82

Offending patch (now reverted):

diff --git Makefile Makefile
index bb0b33c..caa47b4 100644
--- Makefile
+++ Makefile
@@ -11,7 +11,7 @@ GORUN=$(GOCMD) run
 GOBUILD=CGO_ENABLED=$(CGO_ENABLED) $(GOCMD) build -v -buildmode=exe -ldflags $(LD_FLAGS)

 CC_TEST_REPORTER_ID=6e107e510c5479f40b0ce9166a254f3f1ee0bc547b3e48281bada1a5a32bb56d
-GOLANGCI_LINT_VERSION=v1.23.8
+GOLANGCI_LINT_VERSION=v1.24.0
 BIN_PATH=$$HOME/bin

 GO_PACKAGES=./...

Thank you for creating the issue!

  • [x] Yes, I'm using a binary release within 2 latest major releases. Only such installations are supported.
  • [x] Yes, I've searched similar issues on GitHub and didn't find any.
  • [x] Yes, I've included all information below (version, config, etc).

Please include the following information:

Version of golangci-lint

$ golangci-lint --version
golangci-lint has version 1.24.0 built from 6fd4383 on 2020-03-15T11:38:02Z

Config file

$ cat .golangci.yml
cat: .golangci.yml: No such file or directory```

</details>

<details><summary>Go environment</summary>

```console
$ go version && go env
go version go1.14 linux/amd64
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/invidian/.cache/go-build"
GOENV="/home/invidian/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/invidian/go"
GOPRIVATE=""
GOPROXY="http://localhost:8081,https://proxy.golang.org,direct"
GOROOT="/usr/lib/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/invidian/repos/libflexkube/go.mod"
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-build666784723=/tmp/go-build -gno-record-gcc-switches"

Verbose output of running

$ golangci-lint run --enable-all --disable=godox,lll,funlen --max-same-issues=0 --max-issues-per-linter=0 --build-tags integration --timeout 10m --exclude-use-default=false ./... -v
INFO [config_reader] Config search paths: [./ /home/invidian/repos/libflexkube/integration /home/invidian/repos/libflexkube /home/invidian/repos /home/invidian /home /] 
INFO [lintersdb] Active 38 linters: [bodyclose deadcode depguard dogsled dupl errcheck gochecknoglobals gochecknoinits gocognit goconst gocritic gocyclo gofmt goimports golint gomnd goprintffuncname gosec gosimple govet ineffassign interfacer maligned misspell nakedret prealloc rowserrcheck scopelint staticcheck structcheck stylecheck typecheck unconvert unparam unused varcheck whitespace wsl] 
INFO [lintersdb] Active 38 linters: [bodyclose deadcode depguard dogsled dupl errcheck gochecknoglobals gochecknoinits gocognit goconst gocritic gocyclo gofmt goimports golint gomnd goprintffuncname gosec gosimple govet ineffassign interfacer maligned misspell nakedret prealloc rowserrcheck scopelint staticcheck structcheck stylecheck typecheck unconvert unparam unused varcheck whitespace wsl] 
INFO [loader] Go packages loading at mode 575 (compiled_files|exports_file|files|imports|name|deps|types_sizes) took 607.943833ms 
INFO [runner/filename_unadjuster] Pre-built 0 adjustments in 5.466128ms 
INFO [runner/unused/goanalysis] analyzers took 0s with no stages 
INFO [runner/goanalysis_metalinter/goanalysis] analyzers took 0s with no stages 
INFO [runner] Issues before processing: 12, after processing: 0 
INFO [runner] Processors filtering stat (out/in): filename_unadjuster: 12/12, path_prettifier: 12/12, skip_files: 12/12, autogenerated_exclude: 12/12, exclude-rules: 12/12, nolint: 0/12, skip_dirs: 12/12, cgo: 12/12, identifier_marker: 12/12, exclude: 12/12 
INFO [runner] processing took 6.995723ms with stages: nolint: 6.544171ms, identifier_marker: 206.175碌s, path_prettifier: 120.378碌s, autogenerated_exclude: 65.971碌s, skip_dirs: 44.667碌s, cgo: 4.006碌s, max_same_issues: 3.183碌s, uniq_by_line: 1.573碌s, filename_unadjuster: 1.453碌s, max_from_linter: 1.038碌s, diff: 984ns, skip_files: 677ns, source_code: 435ns, path_shortener: 415ns, max_per_file_from_linter: 225ns, exclude: 198ns, exclude-rules: 174ns 
INFO [runner] linters took 238.006384ms with stages: unused: 219.300356ms, goanalysis_metalinter: 11.516494ms 
INFO File cache stats: 0 entries of total size 0B 
INFO Memory: 10 samples, avg is 91.3MB, max is 138.3MB 
INFO Execution took 858.2966ms

cursed help wanted memory

Most helpful comment

I believe @dominikh has been recently working on improving the footprint of his tools.

That is true. However, the vast majority of the footprint lies in how the analyses are run, i.e. the staticcheck command or, in this case, golangci-lint. Though I _am_ working on related changes in unused to aid the runner, which would also benefit golangci-lint.

All 16 comments

We are also experiencing this issue.

I think that is related to #987

I think that is related to #987

Why you think so?

friendly ping @jirfag

Hitting this issue constantly after upgrading to 1.14 and 1.24.0

The latest release of staticcheck is still 2020.1.3 as of this writing.

From comment:

Unused is the only linter that eats a ton of memory because it can't work incrementally. You can disable it. You can make an issue in staticcheck GitHub repository about it: I think its optimization is possible.

Past closed issues:

  • dominikh/go-tools#394
  • dominikh/go-tools#376

My understanding is that there is no open issue for the memory usage of unused in staticcheck.

I wonder if it might be a good idea to warn people who have unused enabled in golangci-lint until it is better optimized in staticcheck.

Hey, I'm very sorry for lack of response :(

You are right, this should be related to unused linter and staticcheck.
I will try to investigate how to fix that. I've hoped that switching from patched staticcheck to upstream will not brake things, but meh.

Current workaround is to disable unused linter.

Any PR that will help to mitigate this issue will be welcomed and reviewed ASAP.

Also, please ping me instead of jirfag.

I believe @dominikh has been recently working on improving the footprint of his tools.

I believe @dominikh has been recently working on improving the footprint of his tools.

That is true. However, the vast majority of the footprint lies in how the analyses are run, i.e. the staticcheck command or, in this case, golangci-lint. Though I _am_ working on related changes in unused to aid the runner, which would also benefit golangci-lint.

Would emitting a warning message whenever the linter is started while unused is enabled cut down on end user confusion (and bug reports) until a better long term solution is in place?

Generating warnings for each unused linter run can be annoying, but seems like it is the only option until OOM is fixed.

Feel free to send PR :zap:

Also it is related to #898

I had to downgrade staticcheck to stabilize project.
Please try v1.25.0 version.

Also please don't blame staticcheck for those issues, they can be caused by the way we are using it.
Will update back only after fixing those issues (on any side).

Closing for now.

Please open new issue for any regression.

Hi,
I've reduced memory usage when running unused in #1063. The problem was in how our loader and runner clears unused fields.

Memory usage on flexkube dropped from 10 GB to 1 GB.

Was this page helpful?
0 / 5 - 0 ratings