< prev index next >

src/hotspot/share/memory/heapInspection.cpp

Print this page




 523  public:
 524   RecordInstanceClosure(KlassInfoTable* cit, BoolObjectClosure* filter) :
 525     _cit(cit), _missed_count(0), _filter(filter) {}
 526 
 527   void do_object(oop obj) {
 528     if (should_visit(obj)) {
 529       if (!_cit->record_instance(obj)) {
 530         _missed_count++;
 531       }
 532     }
 533   }
 534 
 535   size_t missed_count() { return _missed_count; }
 536 
 537  private:
 538   bool should_visit(oop obj) {
 539     return _filter == NULL || _filter->do_object_b(obj);
 540   }
 541 };
 542 








 543 void ParHeapInspectTask::work(uint worker_id) {
 544   size_t missed_count = 0;
 545   if (!_success) {
 546     // other worker has failed on parallel iteration.
 547     return;
 548   }
 549 
 550   KlassInfoTable cit(false);
 551   if (!cit.allocation_failed()) {
 552     RecordInstanceClosure ric(&cit, _filter);
 553     _poi->object_iterate(&ric, worker_id);
 554     missed_count = ric.missed_count();
 555   } else {
 556     // fail to allocate memory, stop parallel mode.
 557     _success = false;
 558     return;
 559   }
 560   {
 561     MutexLocker x(&_mutex);
 562 
 563     if (!_shared_cit->merge(&cit)) {
 564       _success = false;
 565       return;
 566     }
 567     _shared_missed_count += missed_count;
 568   }
 569 }
 570 
 571 size_t HeapInspection::populate_table(KlassInfoTable* cit, BoolObjectClosure *filter, size_t parallel_thread_num) {
 572   ResourceMark rm;
 573 
 574   // Try parallel first.
 575   if (parallel_thread_num > 1) {
 576     ParallelObjectIterator* poi = Universe::heap()->parallel_object_iterator(parallel_thread_num);
 577     if (poi != NULL) {
 578       ParHeapInspectTask task(poi, cit, filter);
 579       Universe::heap()->run_task(&task);


 580       return task.missed_count();

 581     }
 582   }
 583 
 584   // If no parallel iteration available, run serially.
 585   RecordInstanceClosure ric(cit, filter);
 586   Universe::heap()->object_iterate(&ric);
 587   return ric.missed_count();
 588 }
 589 
 590 void HeapInspection::heap_inspection(outputStream* st, size_t parallel_thread_num) {
 591   ResourceMark rm;
 592 
 593   KlassInfoTable cit(false);
 594   if (!cit.allocation_failed()) {
 595     size_t missed_count = 0;;
 596     // populate table with object allocation info
 597     missed_count = populate_table(&cit, NULL, parallel_thread_num);
 598     if (missed_count != 0) {
 599       log_info(gc, classhisto)("WARNING: Ran out of C-heap; undercounted " SIZE_FORMAT
 600                                " total instances in data below",




 523  public:
 524   RecordInstanceClosure(KlassInfoTable* cit, BoolObjectClosure* filter) :
 525     _cit(cit), _missed_count(0), _filter(filter) {}
 526 
 527   void do_object(oop obj) {
 528     if (should_visit(obj)) {
 529       if (!_cit->record_instance(obj)) {
 530         _missed_count++;
 531       }
 532     }
 533   }
 534 
 535   size_t missed_count() { return _missed_count; }
 536 
 537  private:
 538   bool should_visit(oop obj) {
 539     return _filter == NULL || _filter->do_object_b(obj);
 540   }
 541 };
 542 
 543 // Heap inspection for every worker.
 544 // When native OOM hanppens for KlassInfoTable, set _success to false.
 545 // TODO(?) it seems atomically set/get _success is unnecessary becasue it
 546 // is set to true at constructor and can only be set to false here.
 547 // the only risk seems a worker may continue inspect heap when another
 548 // worker set _success to false, but this is OK because the current worker
 549 // doesn't change _success if everything is OK for it's inpection work, and
 550 // the _success will be false finally and serial heap inpection can be tried.
 551 void ParHeapInspectTask::work(uint worker_id) {
 552   size_t missed_count = 0;
 553   if (!_success) {
 554     // other worker has failed on parallel iteration.
 555     return;
 556   }
 557 
 558   KlassInfoTable cit(false);
 559   if (!cit.allocation_failed()) {
 560     RecordInstanceClosure ric(&cit, _filter);
 561     _poi->object_iterate(&ric, worker_id);
 562     missed_count = ric.missed_count();
 563   } else {
 564     // fail to allocate memory, stop parallel mode.
 565     _success = false;
 566     return;
 567   }
 568   {
 569     MutexLocker x(&_mutex);
 570 
 571     if (!_shared_cit->merge(&cit)) {
 572       _success = false;
 573       return;
 574     }
 575     _shared_missed_count += missed_count;
 576   }
 577 }
 578 
 579 size_t HeapInspection::populate_table(KlassInfoTable* cit, BoolObjectClosure *filter, size_t parallel_thread_num) {
 580   ResourceMark rm;
 581 
 582   // Try parallel first.
 583   if (parallel_thread_num > 1) {
 584     ParallelObjectIterator* poi = Universe::heap()->parallel_object_iterator(parallel_thread_num);
 585     if (poi != NULL) {
 586       ParHeapInspectTask task(poi, cit, filter);
 587       Universe::heap()->run_task(&task);
 588       delete poi;
 589       if (task.success()) {
 590         return task.missed_count();
 591       }
 592     }
 593   }
 594 
 595   // If no parallel iteration available, run serially.
 596   RecordInstanceClosure ric(cit, filter);
 597   Universe::heap()->object_iterate(&ric);
 598   return ric.missed_count();
 599 }
 600 
 601 void HeapInspection::heap_inspection(outputStream* st, size_t parallel_thread_num) {
 602   ResourceMark rm;
 603 
 604   KlassInfoTable cit(false);
 605   if (!cit.allocation_failed()) {
 606     size_t missed_count = 0;;
 607     // populate table with object allocation info
 608     missed_count = populate_table(&cit, NULL, parallel_thread_num);
 609     if (missed_count != 0) {
 610       log_info(gc, classhisto)("WARNING: Ran out of C-heap; undercounted " SIZE_FORMAT
 611                                " total instances in data below",


< prev index next >