Skip to content

Commit 3aade55

Browse files
committed
Reduce memory usage of go/analysis
1 parent 358ce7c commit 3aade55

File tree

15 files changed

+369
-184
lines changed

15 files changed

+369
-184
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,7 @@ Global Flags:
560560
-j, --concurrency int Concurrency (default NumCPU) (default 8)
561561
--cpu-profile-path string Path to CPU profile output file
562562
--mem-profile-path string Path to memory profile output file
563+
--trace-path string Path to trace output file
563564
-v, --verbose verbose output
564565
565566
```

pkg/commands/root.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"os"
66
"runtime"
77
"runtime/pprof"
8+
"runtime/trace"
89
"strconv"
910

1011
"github.com/spf13/cobra"
@@ -37,6 +38,16 @@ func (e *Executor) persistentPreRun(_ *cobra.Command, _ []string) {
3738
runtime.MemProfileRate, _ = strconv.Atoi(rate)
3839
}
3940
}
41+
42+
if e.cfg.Run.TracePath != "" {
43+
f, err := os.Create(e.cfg.Run.TracePath)
44+
if err != nil {
45+
e.log.Fatalf("Can't create file %s: %s", e.cfg.Run.TracePath, err)
46+
}
47+
if err = trace.Start(f); err != nil {
48+
e.log.Fatalf("Can't start tracing: %s", err)
49+
}
50+
}
4051
}
4152

4253
func (e *Executor) persistentPostRun(_ *cobra.Command, _ []string) {
@@ -58,6 +69,9 @@ func (e *Executor) persistentPostRun(_ *cobra.Command, _ []string) {
5869
}
5970
f.Close()
6071
}
72+
if e.cfg.Run.TracePath != "" {
73+
trace.Stop()
74+
}
6175

6276
os.Exit(e.exitCode)
6377
}
@@ -136,6 +150,7 @@ func initRootFlagSet(fs *pflag.FlagSet, cfg *config.Config, needVersionOption bo
136150

137151
fs.StringVar(&cfg.Run.CPUProfilePath, "cpu-profile-path", "", wh("Path to CPU profile output file"))
138152
fs.StringVar(&cfg.Run.MemProfilePath, "mem-profile-path", "", wh("Path to memory profile output file"))
153+
fs.StringVar(&cfg.Run.TracePath, "trace-path", "", wh("Path to trace output file"))
139154
fs.IntVarP(&cfg.Run.Concurrency, "concurrency", "j", getDefaultConcurrency(), wh("Concurrency (default NumCPU)"))
140155
if needVersionOption {
141156
fs.BoolVar(&cfg.Run.PrintVersion, "version", false, wh("Print version"))

pkg/commands/run.go

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -451,21 +451,30 @@ func watchResources(ctx context.Context, done chan struct{}, logger logutils.Log
451451
startedAt := time.Now()
452452
debugf("Started tracking time")
453453

454-
var rssValues []uint64
455-
ticker := time.NewTicker(10 * time.Millisecond)
454+
var maxRSSMB, totalRSSMB float64
455+
var iterationsCount int
456+
ticker := time.NewTicker(100 * time.Millisecond)
456457
defer ticker.Stop()
457458

458459
logEveryRecord := os.Getenv("GL_MEM_LOG_EVERY") == "1"
460+
const MB = 1024 * 1024
459461

460462
track := func() {
463+
debugf("Starting memory tracing iteration ...")
461464
var m runtime.MemStats
462465
runtime.ReadMemStats(&m)
463466

464467
if logEveryRecord {
468+
debugf("Stopping memory tracing iteration, printing ...")
465469
printMemStats(&m, logger)
466470
}
467471

468-
rssValues = append(rssValues, m.Sys)
472+
rssMB := float64(m.Sys) / MB
473+
if rssMB > maxRSSMB {
474+
maxRSSMB = rssMB
475+
}
476+
totalRSSMB += rssMB
477+
iterationsCount++
469478
}
470479

471480
for {
@@ -476,7 +485,7 @@ func watchResources(ctx context.Context, done chan struct{}, logger logutils.Log
476485
case <-ctx.Done():
477486
stop = true
478487
debugf("Stopped resources tracking")
479-
case <-ticker.C: // track every second
488+
case <-ticker.C:
480489
}
481490

482491
if stop {
@@ -485,19 +494,10 @@ func watchResources(ctx context.Context, done chan struct{}, logger logutils.Log
485494
}
486495
track()
487496

488-
var avg, max uint64
489-
for _, v := range rssValues {
490-
avg += v
491-
if v > max {
492-
max = v
493-
}
494-
}
495-
avg /= uint64(len(rssValues))
497+
avgRSSMB := totalRSSMB / float64(iterationsCount)
496498

497-
const MB = 1024 * 1024
498-
maxMB := float64(max) / MB
499499
logger.Infof("Memory: %d samples, avg is %.1fMB, max is %.1fMB",
500-
len(rssValues), float64(avg)/MB, maxMB)
500+
iterationsCount, avgRSSMB, maxRSSMB)
501501
logger.Infof("Execution took %s", time.Since(startedAt))
502502
close(done)
503503
}

pkg/config/config.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ type Run struct {
102102
Silent bool
103103
CPUProfilePath string
104104
MemProfilePath string
105+
TracePath string
105106
Concurrency int
106107
PrintResourcesUsage bool `mapstructure:"print-resources-usage"`
107108

pkg/config/reader.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,10 @@ func (r *FileReader) validateConfig() error {
102102
return errors.New("option run.memprofilepath in config isn't allowed")
103103
}
104104

105+
if c.Run.TracePath != "" {
106+
return errors.New("option run.tracepath in config isn't allowed")
107+
}
108+
105109
if c.Run.IsVerbose {
106110
return errors.New("can't set run.verbose option with config: only on command-line")
107111
}

pkg/golinters/goanalysis/linter.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,12 +114,10 @@ func (lnt Linter) Run(ctx context.Context, lintCtx *linter.Context) ([]result.Is
114114
return nil, errors.Wrap(err, "failed to configure analyzers")
115115
}
116116

117-
runner := newRunner(lnt.name, lintCtx.Log.Child("goanalysis"), lintCtx.PkgCache, lintCtx.LoadGuard)
117+
runner := newRunner(lnt.name, lintCtx.Log.Child("goanalysis"), lintCtx.PkgCache, lintCtx.LoadGuard, lintCtx.NeedWholeProgram)
118118

119119
diags, errs := runner.run(lnt.analyzers, lintCtx.Packages)
120-
for i := 1; i < len(errs); i++ {
121-
lintCtx.Log.Warnf("%s error: %s", lnt.Name(), errs[i])
122-
}
120+
// Don't print all errs: they can duplicate.
123121
if len(errs) != 0 {
124122
return nil, errs[0]
125123
}

pkg/golinters/goanalysis/metalinter.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,10 @@ func (ml MetaLinter) Run(ctx context.Context, lintCtx *linter.Context) ([]result
4646
allAnalyzers = append(allAnalyzers, linter.analyzers...)
4747
}
4848

49-
runner := newRunner("metalinter", lintCtx.Log.Child("goanalysis"), lintCtx.PkgCache, lintCtx.LoadGuard)
49+
runner := newRunner("metalinter", lintCtx.Log.Child("goanalysis"), lintCtx.PkgCache, lintCtx.LoadGuard, lintCtx.NeedWholeProgram)
5050

5151
diags, errs := runner.run(allAnalyzers, lintCtx.Packages)
52-
for i := 1; i < len(errs); i++ {
53-
lintCtx.Log.Warnf("go/analysis metalinter error: %s", errs[i])
54-
}
52+
// Don't print all errs: they can duplicate.
5553
if len(errs) != 0 {
5654
return nil, errs[0]
5755
}

0 commit comments

Comments
 (0)