src/share/vm/services/memoryManager.cpp

Print this page




 149 
 150 void MemoryManager::oops_do(OopClosure* f) {
 151   f->do_oop((oop*) &_memory_mgr_obj);
 152 }
 153 
 154 GCStatInfo::GCStatInfo(int num_pools) {
 155   // initialize the arrays for memory usage
 156   _before_gc_usage_array = (MemoryUsage*) NEW_C_HEAP_ARRAY(MemoryUsage, num_pools);
 157   _after_gc_usage_array  = (MemoryUsage*) NEW_C_HEAP_ARRAY(MemoryUsage, num_pools);
 158   size_t len = num_pools * sizeof(MemoryUsage);
 159   memset(_before_gc_usage_array, 0, len);
 160   memset(_after_gc_usage_array, 0, len);
 161   _usage_array_size = num_pools;
 162 }
 163 
 164 GCStatInfo::~GCStatInfo() {
 165   FREE_C_HEAP_ARRAY(MemoryUsage*, _before_gc_usage_array);
 166   FREE_C_HEAP_ARRAY(MemoryUsage*, _after_gc_usage_array);
 167 }
 168 
 169 void GCStatInfo::copy_stat(GCStatInfo* stat) {
 170   set_index(stat->gc_index());
 171   set_start_time(stat->start_time());
 172   set_end_time(stat->end_time());
 173   assert(_usage_array_size == stat->usage_array_size(), "Must have same array size");
 174   for (int i = 0; i < _usage_array_size; i++) {
 175     set_before_gc_usage(i, stat->before_gc_usage_for_pool(i));
 176     set_after_gc_usage(i, stat->after_gc_usage_for_pool(i));
 177   }
 178 }
 179 
 180 void GCStatInfo::set_gc_usage(int pool_index, MemoryUsage usage, bool before_gc) {
 181   MemoryUsage* gc_usage_array;
 182   if (before_gc) {
 183     gc_usage_array = _before_gc_usage_array;
 184   } else {
 185     gc_usage_array = _after_gc_usage_array;
 186   }
 187   gc_usage_array[pool_index] = usage;
 188 }
 189 










 190 GCMemoryManager::GCMemoryManager() : MemoryManager() {
 191   _num_collections = 0;
 192   _last_gc_stat = NULL;


 193   _num_gc_threads = 1;
 194 }
 195 
 196 GCMemoryManager::~GCMemoryManager() {
 197   delete _last_gc_stat;


 198 }
 199 
 200 void GCMemoryManager::initialize_gc_stat_info() {
 201   assert(MemoryService::num_memory_pools() > 0, "should have one or more memory pools");
 202   _last_gc_stat = new GCStatInfo(MemoryService::num_memory_pools());



 203 }
 204 
 205 void GCMemoryManager::gc_begin() {
 206   assert(_last_gc_stat != NULL, "Just checking");


 207   _accumulated_timer.start();
 208   _num_collections++;
 209   _last_gc_stat->set_index(_num_collections);
 210   _last_gc_stat->set_start_time(Management::timestamp());



 211 

 212   // Keep memory usage of all memory pools
 213   for (int i = 0; i < MemoryService::num_memory_pools(); i++) {
 214     MemoryPool* pool = MemoryService::get_memory_pool(i);
 215     MemoryUsage usage = pool->get_memory_usage();
 216     _last_gc_stat->set_before_gc_usage(i, usage);
 217     HS_DTRACE_PROBE8(hotspot, mem__pool__gc__begin,
 218       name(), strlen(name()),
 219       pool->name(), strlen(pool->name()),
 220       usage.init_size(), usage.used(),
 221       usage.committed(), usage.max_size());
 222   }

 223 }
 224 
 225 void GCMemoryManager::gc_end() {






 226   _accumulated_timer.stop();
 227   _last_gc_stat->set_end_time(Management::timestamp());



 228 

 229   int i;
 230   // keep the last gc statistics for all memory pools
 231   for (i = 0; i < MemoryService::num_memory_pools(); i++) {
 232     MemoryPool* pool = MemoryService::get_memory_pool(i);
 233     MemoryUsage usage = pool->get_memory_usage();
 234 
 235     HS_DTRACE_PROBE8(hotspot, mem__pool__gc__end,
 236       name(), strlen(name()),
 237       pool->name(), strlen(pool->name()),
 238       usage.init_size(), usage.used(),
 239       usage.committed(), usage.max_size());
 240 
 241     _last_gc_stat->set_after_gc_usage(i, usage);
 242   }
 243 
 244   // Set last collection usage of the memory pools managed by this collector
 245   for (i = 0; i < num_memory_pools(); i++) {
 246     MemoryPool* pool = get_memory_pool(i);
 247     MemoryUsage usage = pool->get_memory_usage();
 248 
 249     // Compare with GC usage threshold
 250     pool->set_last_collection_usage(usage);
 251     LowMemoryDetector::detect_after_gc_memory(pool);
 252   }




























 253 }


 149 
 150 void MemoryManager::oops_do(OopClosure* f) {
 151   f->do_oop((oop*) &_memory_mgr_obj);
 152 }
 153 
 154 GCStatInfo::GCStatInfo(int num_pools) {
 155   // initialize the arrays for memory usage
 156   _before_gc_usage_array = (MemoryUsage*) NEW_C_HEAP_ARRAY(MemoryUsage, num_pools);
 157   _after_gc_usage_array  = (MemoryUsage*) NEW_C_HEAP_ARRAY(MemoryUsage, num_pools);
 158   size_t len = num_pools * sizeof(MemoryUsage);
 159   memset(_before_gc_usage_array, 0, len);
 160   memset(_after_gc_usage_array, 0, len);
 161   _usage_array_size = num_pools;
 162 }
 163 
 164 GCStatInfo::~GCStatInfo() {
 165   FREE_C_HEAP_ARRAY(MemoryUsage*, _before_gc_usage_array);
 166   FREE_C_HEAP_ARRAY(MemoryUsage*, _after_gc_usage_array);
 167 }
 168 











 169 void GCStatInfo::set_gc_usage(int pool_index, MemoryUsage usage, bool before_gc) {
 170   MemoryUsage* gc_usage_array;
 171   if (before_gc) {
 172     gc_usage_array = _before_gc_usage_array;
 173   } else {
 174     gc_usage_array = _after_gc_usage_array;
 175   }
 176   gc_usage_array[pool_index] = usage;
 177 }
 178 
 179 void GCStatInfo::clear() {
 180   _index = 0;
 181   _start_time = 0L;
 182   _end_time = 0L; 
 183   size_t len = _usage_array_size * sizeof(MemoryUsage);
 184   memset(_before_gc_usage_array, 0, len);
 185   memset(_after_gc_usage_array, 0, len);
 186 }
 187 
 188 
 189 GCMemoryManager::GCMemoryManager() : MemoryManager() {
 190   _num_collections = 0;
 191   _last_gc_stat = NULL;
 192   _last_gc_lock = new Mutex(Mutex::leaf, "_last_gc_lock", true);
 193   _current_gc_stat = NULL;
 194   _num_gc_threads = 1;
 195 }
 196 
 197 GCMemoryManager::~GCMemoryManager() {
 198   delete _last_gc_stat;
 199   delete _last_gc_lock;
 200   delete _current_gc_stat;
 201 }
 202 
 203 void GCMemoryManager::initialize_gc_stat_info() {
 204   assert(MemoryService::num_memory_pools() > 0, "should have one or more memory pools");
 205   _last_gc_stat = new GCStatInfo(MemoryService::num_memory_pools());
 206   _current_gc_stat = new GCStatInfo(MemoryService::num_memory_pools());
 207   // tracking concurrent collections we need two objects: one to update, and one to
 208   // hold the publicly available "last (completed) gc" information.
 209 }
 210 
 211 void GCMemoryManager::gc_begin(bool recordGCBeginTime, bool recordPreGCUsage,
 212                                bool recordAccumulatedGCTime) {
 213   assert(_last_gc_stat != NULL && _current_gc_stat != NULL, "Just checking");
 214   if (recordAccumulatedGCTime) {
 215     _accumulated_timer.start();
 216   }
 217   // _num_collections now increases in gc_end, to count completed collections
 218   if (recordGCBeginTime) {
 219     _current_gc_stat->set_index(_num_collections+1);
 220     _current_gc_stat->set_start_time(Management::timestamp());
 221   }
 222 
 223   if (recordPreGCUsage) {
 224     // Keep memory usage of all memory pools
 225     for (int i = 0; i < MemoryService::num_memory_pools(); i++) {
 226       MemoryPool* pool = MemoryService::get_memory_pool(i);
 227       MemoryUsage usage = pool->get_memory_usage();
 228       _current_gc_stat->set_before_gc_usage(i, usage);
 229       HS_DTRACE_PROBE8(hotspot, mem__pool__gc__begin,
 230         name(), strlen(name()),
 231         pool->name(), strlen(pool->name()),
 232         usage.init_size(), usage.used(),
 233         usage.committed(), usage.max_size());
 234     }
 235   }
 236 }
 237 
 238 // A collector MUST, even if it does not complete for some reason,
 239 // make a TraceMemoryManagerStats object where countCollection is true, 
 240 // to ensure the current gc stat is placed in _last_gc_stat.
 241 void GCMemoryManager::gc_end(bool recordPostGCUsage,
 242                              bool recordAccumulatedGCTime,
 243                              bool recordGCEndTime, bool countCollection) {
 244   if (recordAccumulatedGCTime) {
 245     _accumulated_timer.stop();
 246   }
 247   if (recordGCEndTime) {
 248     _current_gc_stat->set_end_time(Management::timestamp());
 249   }
 250 
 251   if (recordPostGCUsage) {
 252     int i;
 253     // keep the last gc statistics for all memory pools
 254     for (i = 0; i < MemoryService::num_memory_pools(); i++) {
 255       MemoryPool* pool = MemoryService::get_memory_pool(i);
 256       MemoryUsage usage = pool->get_memory_usage();
 257 
 258       HS_DTRACE_PROBE8(hotspot, mem__pool__gc__end,
 259         name(), strlen(name()),
 260         pool->name(), strlen(pool->name()),
 261         usage.init_size(), usage.used(),
 262         usage.committed(), usage.max_size());
 263 
 264       _current_gc_stat->set_after_gc_usage(i, usage);
 265     }
 266 
 267     // Set last collection usage of the memory pools managed by this collector
 268     for (i = 0; i < num_memory_pools(); i++) {
 269       MemoryPool* pool = get_memory_pool(i);
 270       MemoryUsage usage = pool->get_memory_usage();
 271 
 272       // Compare with GC usage threshold
 273       pool->set_last_collection_usage(usage);
 274       LowMemoryDetector::detect_after_gc_memory(pool);
 275     }
 276   }
 277   if (countCollection) {
 278     _num_collections++;
 279     // alternately update two objects making one public when complete
 280     {
 281       MutexLockerEx ml(_last_gc_lock, Mutex::_no_safepoint_check_flag);
 282       GCStatInfo *tmp = _last_gc_stat;
 283       _last_gc_stat = _current_gc_stat;
 284       _current_gc_stat = tmp;
 285       // reset the current stat for diagnosability purposes
 286       _current_gc_stat->clear();
 287     }
 288   }
 289 }
 290 
 291 size_t GCMemoryManager::get_last_gc_stat(GCStatInfo* dest) {
 292   MutexLockerEx ml(_last_gc_lock, Mutex::_no_safepoint_check_flag);
 293   if (_last_gc_stat->gc_index() != 0) { 
 294     dest->set_index(_last_gc_stat->gc_index());
 295     dest->set_start_time(_last_gc_stat->start_time());
 296     dest->set_end_time(_last_gc_stat->end_time());
 297     assert(dest->usage_array_size() == _last_gc_stat->usage_array_size(),
 298            "Must have same array size");
 299     size_t len = dest->usage_array_size() * sizeof(MemoryUsage);
 300     memcpy(dest->before_gc_usage_array(), _last_gc_stat->before_gc_usage_array(), len);
 301     memcpy(dest->after_gc_usage_array(), _last_gc_stat->after_gc_usage_array(), len);
 302   }
 303   return _last_gc_stat->gc_index();
 304 }