summaryrefslogtreecommitdiff
path: root/src/gc
diff options
context:
space:
mode:
authorMaoni Stephens <Maoni0@users.noreply.github.com>2018-04-02 11:10:48 -0700
committerGitHub <noreply@github.com>2018-04-02 11:10:48 -0700
commit2583ce936776a0eac31df904e41d5119840c203b (patch)
tree987571beacb459f7e7fa9ad79cb0d0c013068cc1 /src/gc
parent73fe1a9b6dd1983e35093139bf50ede2b78bbf14 (diff)
downloadcoreclr-2583ce936776a0eac31df904e41d5119840c203b.tar.gz
coreclr-2583ce936776a0eac31df904e41d5119840c203b.tar.bz2
coreclr-2583ce936776a0eac31df904e41d5119840c203b.zip
Added a new API to provide memory information that GC records. This (#17326)
is to be used by BCL for deciding when to trim memory usage in pooling code
Diffstat (limited to 'src/gc')
-rw-r--r--src/gc/gc.cpp66
-rw-r--r--src/gc/gcimpl.h6
-rw-r--r--src/gc/gcinterface.h14
-rw-r--r--src/gc/gcpriv.h13
4 files changed, 92 insertions, 7 deletions
diff --git a/src/gc/gc.cpp b/src/gc/gc.cpp
index a23edb9dff..ef9058e6ab 100644
--- a/src/gc/gc.cpp
+++ b/src/gc/gc.cpp
@@ -2467,13 +2467,19 @@ double gc_heap::short_plugs_pad_ratio = 0;
size_t gc_heap::youngest_gen_desired_th;
#endif //BIT64
-uint64_t gc_heap::mem_one_percent;
+uint32_t gc_heap::last_gc_memory_load = 0;
-uint32_t gc_heap::high_memory_load_th;
+size_t gc_heap::last_gc_heap_size = 0;
-uint64_t gc_heap::total_physical_mem;
+size_t gc_heap::last_gc_fragmentation = 0;
-uint64_t gc_heap::entry_available_physical_mem;
+uint64_t gc_heap::mem_one_percent = 0;
+
+uint32_t gc_heap::high_memory_load_th = 0;
+
+uint64_t gc_heap::total_physical_mem = 0;
+
+uint64_t gc_heap::entry_available_physical_mem = 0;
#ifdef BACKGROUND_GC
GCEvent gc_heap::bgc_start_event;
@@ -5755,9 +5761,8 @@ void gc_mechanisms::init_mechanisms()
allocations_allowed = TRUE;
#endif //BACKGROUND_GC
-#ifdef BIT64
entry_memory_load = 0;
-#endif // BIT64
+ exit_memory_load = 0;
#ifdef STRESS_HEAP
stress_induced = FALSE;
@@ -19096,6 +19101,28 @@ size_t gc_heap::get_total_heap_size()
return total_heap_size;
}
+size_t gc_heap::get_total_fragmentation()
+{
+ size_t total_fragmentation = 0;
+
+#ifdef MULTIPLE_HEAPS
+ for (int i = 0; i < gc_heap::n_heaps; i++)
+ {
+ gc_heap* hp = gc_heap::g_heaps[i];
+#else //MULTIPLE_HEAPS
+ {
+ gc_heap* hp = pGenGCHeap;
+#endif //MULTIPLE_HEAPS
+ for (int i = 0; i <= (max_generation + 1); i++)
+ {
+ generation* gen = hp->generation_of (i);
+ total_fragmentation += (generation_free_list_space (gen) + generation_free_obj_space (gen));
+ }
+ }
+
+ return total_fragmentation;
+}
+
size_t gc_heap::committed_size()
{
generation* gen = generation_of (max_generation);
@@ -29663,8 +29690,11 @@ size_t gc_heap::desired_new_allocation (dynamic_data* dd,
}
else //large object heap
{
+ uint32_t memory_load = 0;
uint64_t available_physical = 0;
- get_memory_info (NULL, &available_physical);
+ get_memory_info (&memory_load, &available_physical);
+ if (heap_number == 0)
+ settings.exit_memory_load = memory_load;
if (available_physical > 1024*1024)
available_physical -= 1024*1024;
@@ -29899,6 +29929,7 @@ size_t gc_heap::joined_youngest_desired (size_t new_allocation)
{
uint32_t memory_load = 0;
get_memory_info (&memory_load);
+ settings.exit_memory_load = memory_load;
dprintf (2, ("Current emory load: %d", memory_load));
size_t final_total =
@@ -34882,6 +34913,14 @@ void gc_heap::do_post_gc()
settings.condemned_generation,
(settings.concurrent ? "BGC" : "GC")));
+ if (settings.exit_memory_load != 0)
+ last_gc_memory_load = settings.exit_memory_load;
+ else if (settings.entry_memory_load != 0)
+ last_gc_memory_load = settings.entry_memory_load;
+
+ last_gc_heap_size = get_total_heap_size();
+ last_gc_fragmentation = get_total_fragmentation();
+
GCHeap::UpdatePostGCCounters();
#ifdef FEATURE_APPDOMAIN_RESOURCE_MONITORING
//if (g_fEnableARM)
@@ -35266,6 +35305,19 @@ unsigned int GCHeap::GetCondemnedGeneration()
return gc_heap::settings.condemned_generation;
}
+void GCHeap::GetMemoryInfo(uint32_t* highMemLoadThreshold,
+ uint64_t* totalPhysicalMem,
+ uint32_t* lastRecordedMemLoad,
+ size_t* lastRecordedHeapSize,
+ size_t* lastRecordedFragmentation)
+{
+ *highMemLoadThreshold = gc_heap::high_memory_load_th;
+ *totalPhysicalMem = gc_heap::total_physical_mem;
+ *lastRecordedMemLoad = gc_heap::last_gc_memory_load;
+ *lastRecordedHeapSize = gc_heap::last_gc_heap_size;
+ *lastRecordedFragmentation = gc_heap::last_gc_fragmentation;
+}
+
int GCHeap::GetGcLatencyMode()
{
return (int)(pGenGCHeap->settings.pause_mode);
diff --git a/src/gc/gcimpl.h b/src/gc/gcimpl.h
index 261e26e9aa..54aee1a2ed 100644
--- a/src/gc/gcimpl.h
+++ b/src/gc/gcimpl.h
@@ -168,6 +168,12 @@ public:
unsigned GetCondemnedGeneration();
+ void GetMemoryInfo(uint32_t* highMemLoadThreshold,
+ uint64_t* totalPhysicalMem,
+ uint32_t* lastRecordedMemLoad,
+ size_t* lastRecordedHeapSize,
+ size_t* lastRecordedFragmentation);
+
int GetGcLatencyMode();
int SetGcLatencyMode(int newLatencyMode);
diff --git a/src/gc/gcinterface.h b/src/gc/gcinterface.h
index c7c6424d00..d532c8a13a 100644
--- a/src/gc/gcinterface.h
+++ b/src/gc/gcinterface.h
@@ -608,6 +608,20 @@ public:
===========================================================================
*/
+ // Gets memory related information -
+ // highMemLoadThreshold - physical memory load (in percentage) when GC will start to
+ // react aggressively to reclaim memory.
+ // totalPhysicalMem - the total amount of phyiscal memory available on the machine and the memory
+ // limit set on the container if running in a container.
+ // lastRecordedMemLoad - physical memory load in percentage recorded in the last GC
+ // lastRecordedHeapSize - total managed heap size recorded in the last GC
+ // lastRecordedFragmentation - total fragmentation in the managed heap recorded in the last GC
+ virtual void GetMemoryInfo(uint32_t* highMemLoadThreshold,
+ uint64_t* totalPhysicalMem,
+ uint32_t* lastRecordedMemLoad,
+ size_t* lastRecordedHeapSize,
+ size_t* lastRecordedFragmentation) = 0;
+
// Gets the current GC latency mode.
virtual int GetGcLatencyMode() = 0;
diff --git a/src/gc/gcpriv.h b/src/gc/gcpriv.h
index 2c66acef4a..90717420ce 100644
--- a/src/gc/gcpriv.h
+++ b/src/gc/gcpriv.h
@@ -489,7 +489,9 @@ public:
BOOL stress_induced;
#endif // STRESS_HEAP
+ // These are opportunistically set
uint32_t entry_memory_load;
+ uint32_t exit_memory_load;
void init_mechanisms(); //for each GC
void first_init(); // for the life of the EE
@@ -2479,6 +2481,8 @@ protected:
size_t get_total_heap_size ();
PER_HEAP_ISOLATED
size_t get_total_committed_size();
+ PER_HEAP_ISOLATED
+ size_t get_total_fragmentation();
PER_HEAP_ISOLATED
void get_memory_info (uint32_t* memory_load,
@@ -2969,6 +2973,15 @@ public:
#endif //BIT64
PER_HEAP_ISOLATED
+ uint32_t last_gc_memory_load;
+
+ PER_HEAP_ISOLATED
+ size_t last_gc_heap_size;
+
+ PER_HEAP_ISOLATED
+ size_t last_gc_fragmentation;
+
+ PER_HEAP_ISOLATED
uint32_t high_memory_load_th;
PER_HEAP_ISOLATED