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
5982
void Utils::tryShrinkHeap() {
30
5982
#if defined(TCMALLOC) || defined(GPERFTOOLS_TCMALLOC)
31
5982
  auto total_physical_bytes = Stats::totalPhysicalBytes();
32
5982
  auto allocated_size_by_app = Stats::totalCurrentlyAllocated();
33
5982
  const uint64_t threshold = maxUnfreedMemoryBytes();
34

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

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