1
#include "source/common/memory/utils.h"
2

            
3
#include "source/common/common/assert.h"
4
#include "source/common/memory/stats.h"
5

            
6
#if defined(TCMALLOC)
7
#include "tcmalloc/malloc_extension.h"
8
#elif defined(GPERFTOOLS_TCMALLOC)
9
#include "gperftools/malloc_extension.h"
10
#endif
11

            
12
namespace Envoy {
13
namespace Memory {
14

            
15
10
void Utils::releaseFreeMemory() {
16
#if defined(TCMALLOC)
17
  tcmalloc::MallocExtension::ReleaseMemoryToSystem(maxUnfreedMemoryBytes());
18
#elif defined(GPERFTOOLS_TCMALLOC)
19
  MallocExtension::instance()->ReleaseFreeMemory();
20
10
#endif
21
10
}
22

            
23
/*
24
  The purpose of this function is to release the cache introduced by tcmalloc,
25
  mainly in xDS config updates, admin handler, and so on. all work on the main thread,
26
  so the overall impact on performance is small.
27
  Ref: https://github.com/envoyproxy/envoy/pull/9471#discussion_r363825985
28
*/
29
6064
void Utils::tryShrinkHeap() {
30
6064
#if defined(TCMALLOC) || defined(GPERFTOOLS_TCMALLOC)
31
6064
  auto total_physical_bytes = Stats::totalPhysicalBytes();
32
6064
  auto allocated_size_by_app = Stats::totalCurrentlyAllocated();
33
6064
  const uint64_t threshold = maxUnfreedMemoryBytes();
34

            
35
6064
  if (total_physical_bytes >= allocated_size_by_app &&
36
6064
      (total_physical_bytes - allocated_size_by_app) >= threshold) {
37
8
    Utils::releaseFreeMemory();
38
8
  }
39
6064
#endif
40
6064
}
41

            
42
} // namespace Memory
43
} // namespace Envoy