From e337cae0c5b727f411fff90a9aa0aa78a72ca994 Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Tue, 15 Oct 2019 16:33:09 +0100 Subject: [PATCH] accounting: fix memory leak noticeable for transfers of large numbers of objects Before this fix we weren't removing transfers from the transfer stats. For transfers with 1000s of objects this uses a noticeable amount of memory. See: https://forum.rclone.org/t/rclone-memory-consumption-increasing-linearly/12244 --- fs/accounting/stats.go | 13 +++++++++++++ fs/accounting/transfer.go | 1 + 2 files changed, 14 insertions(+) diff --git a/fs/accounting/stats.go b/fs/accounting/stats.go index d31b23158..36818b01b 100644 --- a/fs/accounting/stats.go +++ b/fs/accounting/stats.go @@ -532,3 +532,16 @@ func (s *StatsInfo) AddTransfer(transfer *Transfer) { s.startedTransfers = append(s.startedTransfers, transfer) s.mu.Unlock() } + +// RemoveTransfer removes a reference to the started transfer. +func (s *StatsInfo) RemoveTransfer(transfer *Transfer) { + s.mu.Lock() + for i, tr := range s.startedTransfers { + if tr == transfer { + // remove the found entry + s.startedTransfers = append(s.startedTransfers[:i], s.startedTransfers[i+1:]...) + break + } + } + s.mu.Unlock() +} diff --git a/fs/accounting/transfer.go b/fs/accounting/transfer.go index a7015b918..41a5536b3 100644 --- a/fs/accounting/transfer.go +++ b/fs/accounting/transfer.go @@ -113,6 +113,7 @@ func (tr *Transfer) Done(err error) { } else { tr.stats.DoneTransferring(tr.remote, err == nil) } + tr.stats.RemoveTransfer(tr) } // Reset allows to switch the Account to another transfer method.