From 09a31fa910fb3fe339dd9a60987abfd6aff2f9c0 Mon Sep 17 00:00:00 2001 From: Jarek Kowalski Date: Sat, 24 Aug 2019 11:58:08 -0700 Subject: [PATCH] =?UTF-8?q?cli:=20added=20-=E2=80=93track-memory-usage=20f?= =?UTF-8?q?lag=20that=20periodically=20logs=20memory=20usage?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cli/app.go | 3 +++ cli/memory_tracking.go | 53 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 cli/memory_tracking.go diff --git a/cli/app.go b/cli/app.go index dfea4055c..443d46411 100644 --- a/cli/app.go +++ b/cli/app.go @@ -57,6 +57,9 @@ func serverAction(act func(ctx context.Context, cli *serverapi.Client) error) fu func repositoryAction(act func(ctx context.Context, rep *repo.Repository) error) func(ctx *kingpin.ParseContext) error { return func(kpc *kingpin.ParseContext) error { return withProfiling(func() error { + startMemoryTracking() + defer finishMemoryTracking() + ctx := context.Background() ctx = content.UsingContentCache(ctx, *enableCaching) ctx = content.UsingListCache(ctx, *enableListCaching) diff --git a/cli/memory_tracking.go b/cli/memory_tracking.go new file mode 100644 index 000000000..53c1e108d --- /dev/null +++ b/cli/memory_tracking.go @@ -0,0 +1,53 @@ +package cli + +import ( + "runtime" + "sync" + "time" + + "github.com/kopia/kopia/internal/kopialogging" +) + +var trackMemoryUsage = app.Flag("track-memory-usage", "Periodically force GC and log current memory usage").Hidden().Duration() + +var memlog = kopialogging.Logger("kopia/memory") + +var ( + memoryTrackerMutex sync.Mutex + lastHeapUsage, lastStackInUse uint64 + maxHeapUsage, maxStackInUse uint64 +) + +func dumpMemoryUsage() { + runtime.GC() + var ms runtime.MemStats + runtime.ReadMemStats(&ms) + + memoryTrackerMutex.Lock() + defer memoryTrackerMutex.Unlock() + memlog.Debugf("in use heap %v (delta %v max %v) stack %v (delta %v max %v)", ms.HeapInuse, int64(ms.HeapInuse-lastHeapUsage), maxHeapUsage, ms.StackInuse, int64(ms.StackInuse-lastStackInUse), maxStackInUse) + if ms.HeapInuse > maxHeapUsage { + maxHeapUsage = ms.HeapInuse + } + if ms.StackInuse > maxStackInUse { + maxStackInUse = ms.StackInuse + } + lastHeapUsage = ms.HeapInuse + lastStackInUse = ms.StackInuse +} + +func startMemoryTracking() { + if *trackMemoryUsage > 0 { + + go func() { + for { + dumpMemoryUsage() + time.Sleep(*trackMemoryUsage) + } + }() + } +} + +func finishMemoryTracking() { + dumpMemoryUsage() +}