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 } | 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 _current_gc_stat = NULL; 194 _num_gc_threads = 1; 195 } 196 197 GCMemoryManager::~GCMemoryManager() { 198 delete _last_gc_stat; 199 delete _current_gc_stat; 200 } 201 202 void GCMemoryManager::initialize_gc_stat_info() { 203 assert(MemoryService::num_memory_pools() > 0, "should have one or more memory pools"); 204 _last_gc_stat = new GCStatInfo(MemoryService::num_memory_pools()); 205 _current_gc_stat = new GCStatInfo(MemoryService::num_memory_pools()); 206 // tracking concurrent collections requires two objects: one to update, and one to 207 // be the publicly available "last (completed) gc". 208 } 209 210 void GCMemoryManager::gc_begin(bool recordGCBeginTime, bool recordPreGCUsage, 211 bool recordAccumulatedGCTime) { 212 assert(_last_gc_stat != NULL && _current_gc_stat != NULL, "Just checking"); 213 if (recordAccumulatedGCTime) { 214 _accumulated_timer.start(); 215 } 216 // _num_collections now increases in gc_end, to count completed collections 217 if (recordGCBeginTime) { 218 _current_gc_stat->set_index(_num_collections+1); 219 _current_gc_stat->set_start_time(Management::timestamp()); 220 } 221 222 if (recordPreGCUsage) { 223 // Keep memory usage of all memory pools 224 for (int i = 0; i < MemoryService::num_memory_pools(); i++) { 225 MemoryPool* pool = MemoryService::get_memory_pool(i); 226 MemoryUsage usage = pool->get_memory_usage(); 227 _current_gc_stat->set_before_gc_usage(i, usage); 228 HS_DTRACE_PROBE8(hotspot, mem__pool__gc__begin, 229 name(), strlen(name()), 230 pool->name(), strlen(pool->name()), 231 usage.init_size(), usage.used(), 232 usage.committed(), usage.max_size()); 233 } 234 } 235 } 236 237 // A collector MUST, even if it does not complete for some reason, 238 // make a TraceMemoryManagerStats object where countCollection is true, 239 // to ensure the current gc stat is placed in _last_gc_stat. 240 void GCMemoryManager::gc_end(bool recordPostGCUsage, 241 bool recordAccumulatedGCTime, 242 bool recordGCEndTime, bool countCollection) { 243 if (recordAccumulatedGCTime) { 244 _accumulated_timer.stop(); 245 } 246 if (recordGCEndTime) { 247 _current_gc_stat->set_end_time(Management::timestamp()); 248 } 249 250 if (recordPostGCUsage) { 251 int i; 252 // keep the last gc statistics for all memory pools 253 for (i = 0; i < MemoryService::num_memory_pools(); i++) { 254 MemoryPool* pool = MemoryService::get_memory_pool(i); 255 MemoryUsage usage = pool->get_memory_usage(); 256 257 HS_DTRACE_PROBE8(hotspot, mem__pool__gc__end, 258 name(), strlen(name()), 259 pool->name(), strlen(pool->name()), 260 usage.init_size(), usage.used(), 261 usage.committed(), usage.max_size()); 262 263 _current_gc_stat->set_after_gc_usage(i, usage); 264 } 265 266 // Set last collection usage of the memory pools managed by this collector 267 for (i = 0; i < num_memory_pools(); i++) { 268 MemoryPool* pool = get_memory_pool(i); 269 MemoryUsage usage = pool->get_memory_usage(); 270 271 // Compare with GC usage threshold 272 pool->set_last_collection_usage(usage); 273 LowMemoryDetector::detect_after_gc_memory(pool); 274 } 275 } 276 if (countCollection) { 277 _num_collections++; 278 // alternately update two objects making one public when complete 279 GCStatInfo *tmp = _last_gc_stat; 280 _last_gc_stat = _current_gc_stat; 281 _current_gc_stat = tmp; 282 #ifdef ASSERT 283 // reset the current stat for diagnosability purposes 284 _current_gc_stat->set_index(0); 285 _current_gc_stat->set_start_time(0); 286 _current_gc_stat->set_end_time(0); 287 for (int i = 0; i < MemoryService::num_memory_pools(); i++) { 288 MemoryUsage empty_usage = MemoryUsage(); 289 _current_gc_stat->set_before_gc_usage(i, empty_usage); 290 _current_gc_stat->set_after_gc_usage(i, empty_usage); 291 } 292 #endif 293 } 294 } |