diff options
author | Maoni Stephens <Maoni0@users.noreply.github.com> | 2018-04-02 11:10:48 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-04-02 11:10:48 -0700 |
commit | 2583ce936776a0eac31df904e41d5119840c203b (patch) | |
tree | 987571beacb459f7e7fa9ad79cb0d0c013068cc1 /src/gc | |
parent | 73fe1a9b6dd1983e35093139bf50ede2b78bbf14 (diff) | |
download | coreclr-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.cpp | 66 | ||||
-rw-r--r-- | src/gc/gcimpl.h | 6 | ||||
-rw-r--r-- | src/gc/gcinterface.h | 14 | ||||
-rw-r--r-- | src/gc/gcpriv.h | 13 |
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 |